/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.common.electricsent.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.core.config.CfRedisRepository;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.annotation.CaseChangeReportData;
import com.icinfo.cloud.provider.common.config.RedisUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.*;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.*;
import com.icinfo.cloud.provider.punish.common.caseregister.service.IRegisterCommonService;
import com.icinfo.cloud.provider.punish.common.documentoperate.dto.*;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentStatusEnum;
import com.icinfo.cloud.provider.punish.common.documentoperate.service.IStageDocCommonOperateService;
import com.icinfo.cloud.provider.punish.common.documentoperate.vo.DocumentCommonFormDataVo;
import com.icinfo.cloud.provider.punish.common.electricsent.SentReceiptDocQueryDto;
import com.icinfo.cloud.provider.punish.common.electricsent.dto.*;
import com.icinfo.cloud.provider.punish.common.electricsent.enums.DocumentSendStatusEnum;
import com.icinfo.cloud.provider.punish.common.electricsent.enums.RealPlaceSentTypeEnum;
import com.icinfo.cloud.provider.punish.common.electricsent.enums.SendWayEnum;
import com.icinfo.cloud.provider.punish.common.electricsent.enums.SentRegisterReceiverTypeEnum;
import com.icinfo.cloud.provider.punish.common.electricsent.mapper.DocumentSendRecordMapper;
import com.icinfo.cloud.provider.punish.common.electricsent.model.DocumentSendRecord;
import com.icinfo.cloud.provider.punish.common.electricsent.service.IAppDocumentSentFlowService;
import com.icinfo.cloud.provider.punish.common.electricsent.service.IDocumentSendRecordService;
import com.icinfo.cloud.provider.punish.common.electricsent.service.IDocumentSentFlowService;
import com.icinfo.cloud.provider.punish.common.electricsent.vo.*;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamDocumentInfo;
import com.icinfo.cloud.provider.punish.config.model.SysDepartParam;
import com.icinfo.cloud.provider.punish.config.service.IConfigBusiParamDocumentInfoService;
import com.icinfo.cloud.provider.punish.config.service.ISysDepartParamService;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseAttachmentInfoQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseAttachmentInfoSaveDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseDocumentRecordDelRequest;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CasePartiesRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.*;
import com.icinfo.cloud.provider.punish.ucase.investigateevidence.mapper.CaseDocumentSendinfoConfirmMapper;
import com.icinfo.cloud.provider.punish.ucase.investigateevidence.model.CaseDocumentSendinfoConfirm;
import com.icinfo.cloud.provider.punish.ucase.investigateevidence.service.ICaseDocumentSendinfoConfirmService;
import com.icinfo.cloud.workflow.common.annotation.WorkFlowRollAnnotation;
import com.icinfo.cloud.workflow.config.mapper.ConfigWorkFlowDocumentSentMapper;
import com.icinfo.cloud.workflow.config.model.ConfigWorkFlowDocumentSent;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述：文书送达流程接口实现类
 *
 * @author xiangyuyu
 * @date 2022-02-18 14:50
 */
@Service
@Slf4j
public class DocumentSentFlowServiceImpl implements IDocumentSentFlowService {

    @Value("${sms.url}")
    private String masSmsUrl;

    @Value("${sms.ecName}")
    private String ecName;

    @Value("${sms.apId}")
    private String apId;

    @Value("${sms.secretKey}")
    private String secretKey;

    @Value("${sms.sign}")
    private String sign;

    @Value("${sms.addSerial}")
    private String addSerial = "";

    @Value("${sms.servercode}")
    private String serverCode;

    @Value("${sms.serverpwd}")
    private String serverPwd;

    @Value("${sms.provinceUrl}")
    private String provinceUrl;

    @Resource
    private ICaseDocumentRecordService caseDocumentRecordService;
    @Resource
    private IConfigBusiParamDocumentInfoService configBusiParamDocumentInfoService;
    @Resource
    private IDocumentSendRecordService documentSendRecordService;
    @Resource
    private ICaseDocumentSendinfoConfirmService documentSendinfoConfirmService;
    @Resource
    private IStageDocCommonOperateService stageDocCommonOperateService;
    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private ICaseHandlePersonRecordService caseHandlePersonRecordService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private CaseAppendixRecordMapper caseAppendixRecordMapper;
    @Resource
    private CaseDocumentSendinfoConfirmMapper caseDocumentSendinfoConfirmMapper;
    @Resource
    private ICaseAppendixRecordService caseAppendixRecordService;
    @Resource
    private IDocumentSentFlowService documentSentFlowService;
    @Resource
    private DocumentSendRecordMapper documentSendRecordMapper;
    @Resource
    private ConfigWorkFlowDocumentSentMapper configWorkFlowDocumentSentMapper;
    @Resource
    private ICasePunishDecisionRevokeRecordService casePunishDecisionRevokeRecordService;
    @Resource
    private IAppDocumentSentFlowService appDocumentSentFlowService;
    @Resource
    private IRegisterCommonService registerCommonService;
    @Resource
    private ISysDepartParamService sysDepartParamService;
    @Resource
    private CaseReasonMainRecordMapper caseReasonMainRecordMapper;
    @Resource
    private CfRedisRepository cfRedisRepository;
    @Resource
    private CaseMainInfoMapper caseMainInfoMapper;
    @Resource
    private CaseMainDetailAuxiliaryInfoMapper caseMainDetailAuxiliaryInfoMapper;
    @Resource
    private CaseMainDetailInfoMapper caseMainDetailInfoMapper;

    /**
     * 描述：发送短信
     *
     * @param mobiles 手机号，多个用英文逗号分隔（每批次限5000个号码）
     * @param content 短信内容
     * @return 发送结果(错误时返回错误信息 ， 成功返回空值)
     * @author xiangyuyu
     * @date 2022-02-26 13:58
     */
    @Override
    public String sendSms(String mobiles, String content) {
        log.info("sendCommonSms start...param(mobiles:{} content:{})", mobiles, content);
        //校验是否需要发送
        if (!verifySend(mobiles)) {
            return "";
        }
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("ecName", ecName);
        paramMap.put("apId", apId);
        paramMap.put("mobiles", mobiles);
        paramMap.put("content", content);
        paramMap.put("sign", sign);
        paramMap.put("addSerial", addSerial);
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(ecName).append(apId).append(secretKey).append(mobiles).append(content).append(sign).append(addSerial);
        String mac = "";
        try {
            mac = Md5Util.md5(stringBuffer.toString());
        } catch (Exception e) {
            log.error("md5加密异常:{}", e);
        }
        paramMap.put("mac", mac);
        String paramStr = JSON.toJSONString(paramMap);
        log.info("发送短信入参：{}", paramStr);
        String base64 = Base64Utils.encodeToString(paramStr.getBytes());
        log.info("发送短信入参base64：{}", base64);
        String result = HttpUtil.post(masSmsUrl + "/sms/norsubmit", base64);
        //解析结果
        JSONObject jsonResult = JSON.parseObject(result);
        log.info("sendCommonSms end...result-jsonResult:{}", jsonResult.toJSONString());
        if (jsonResult.getBoolean(Constant.STRING_SUCCESS_EN)) {
            return "";
        } else {
            return jsonResult.getString("rspcod");
        }
    }

    /**
     * 描述：发送短信【省级通用】
     *
     * @param mobiles   手机号码
     * @param content   短信内容
     * @param messageId 短信id【可不传】
     * @return 发送结果(错误时返回错误信息 ， 成功返回空值)
     * @author xiangyuyu
     * @date 2022/8/28
     * @since 1.4.1
     */
    @Override
    public String sendSmsProvince(String mobiles, String content, String messageId) {
        //校验是否发送
        if (!verifySend(mobiles)) {
            return "";
        }
        //消息发送时间
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        //serverCode+serverPwd+time
        String sign;
        try {
            /*sign = Md5Utils.md5(serverCode + serverPwd + time);
            //短号
            String srcNum = "3313";
            //0:对方接收手机号码     1：对方登录名
            String desttype = "0";
            Map<String, Object> paraM = new HashMap<>(20);
            paraM.put("servercode", serverCode);
            paraM.put("time", time);
            paraM.put("sign", sign);
            paraM.put("srcnum", srcNum);
            paraM.put("desttype", desttype);
            paraM.put("dest", mobiles);
            paraM.put("message", content);
            paraM.put("messageid", messageId);
            log.info("sendSmsProvince start param:" + paraM);
            String result = HttpUtils.doHttpPost(provinceUrl, paraM);*/
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("username","zhzf");
            jsonObject.put("password","Cq123456?");
            String contentStr=content.replace("http://23.99.94.216:33180/fastdfs","http://183.230.113.144:41130/fastdfs");
            jsonObject.put("msg",contentStr);
            jsonObject.put("phone",mobiles);
            String result = HttpUtils.doPostJson(provinceUrl,jsonObject.toJSONString());
            log.info("sendSmsProvince end result:" + result);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return "短信发送失败-" + e.getMessage();
        }
    }

    private boolean verifySend(String mobiles) {
        if (!SpringContextUtil.checkIsDevProfile()) {
            return true;
        }
        List<String> whiteList = Arrays.asList("18867145561", "18258059476", "18868876270", "13675896316", "13772230073", "15988178317", "16605755011", "17353109833");
        if (!whiteList.contains(mobiles)) {
            log.info("测试环境跳过短信机以减少真实短信交互，如真实需要，请开放短信发送");
            return false;
        }
        return true;
    }

    /**
     * 【V1.0.0】描述：获取送达流程详情数据
     *
     * @param queryDto {@link DocumentSentFlowDetailInfoQueryDto}
     * @return {@link DocumentSentFlowDetailInfoVo} 送达流程详情数据
     * @author xiangyuyu
     * @date 2022-02-16 16:02
     */
    @Override
    public DocumentSentFlowDetailInfoVo getDocumentSentFlowDetailInfo(DocumentSentFlowDetailInfoQueryDto queryDto) {

        String caseId = queryDto.getCaseId();
        String partyId = queryDto.getPartyId();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        /*
        //送达详情都开放给他们看，具体里面的操作控制
        if(caseMainInfoService.validateCaseIsInNotDealStatus(caseMainInfo,null)){
            throw new BusinessException("当前案件状态不允许进行该操作");
        }*/
        String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
        if (ObjectUtils.isEmpty(partyId)) {
            if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                throw new BusinessException("多当事人时送达流程指定当事人id");
            }
        }
        DocumentSentFlowDetailInfoVo vo = new DocumentSentFlowDetailInfoVo();
        //获取文书记录信息
        String documentId = queryDto.getDocumentId();
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        boolean isCaseRelateDocument = caseId.equalsIgnoreCase(caseDocumentRecord.getCaseId());
        if(!isCaseRelateDocument){
            throw new BusinessException("文书与案件不匹配");
        }
        String documentCatalogCode = caseDocumentRecord.getDocumentCatalogCode();
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
        String documentKindCode = configBusiParamDocumentInfo.getDocumentKindCode();
        //根据文书目录编码获取送达回证文书目录编码 -- 优化从数据库获取
        ConfigBusiParamDocumentInfo sdhzConfig = configBusiParamDocumentInfoService.getSDHZDetailBySentDocumentCatalogCode(documentCatalogCode);
        String sentReceiptPrintDocumentCatalogCode = sdhzConfig.getDocumentCatalogCode();

        /*if(Constant.TZ_BUSI_PARAM_ID.equals(configBusiParamDocumentInfo.getBusiParamId())){
            sentReceiptPrintDocumentCatalogCode = Constant.TZ_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(documentKindCode);
        }else{
            sentReceiptPrintDocumentCatalogCode = Constant.QS_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(documentKindCode);
        }*/

        vo.setSentReceiptPrintDocumentCatalogCode(sentReceiptPrintDocumentCatalogCode);
        LocalDateTime now = LocalDateTime.now();
        LocalDate sentDeadline = caseDocumentRecord.getSentDeadline();
        if (ObjectUtils.isEmpty(sentDeadline)) {
            throw new BusinessException("文书未生成送达截止日期");
        }
        LocalDateTime sentDeadlineTime = sentDeadline.atTime(23, 59, 59);
        HashMap<String, String> map = DateUtil.calculateTimeIntervalInfo(now, sentDeadlineTime, true);
        String sign = map.get("sign");
        String remaining = map.get("showTime");
        if (Constant.STRING_1.equals(sign)) {
            //剩余时间
            remaining = "剩" + remaining;
        } else {
            remaining = "超期" + remaining;
            remaining = remaining.replace("-", "");
        }
        //基本信息
        LocalDateTime sentTime = caseDocumentRecord.getSentTime();
        DocumentSendRecordVo firstRecord = new DocumentSendRecordVo();
        boolean hadSendRecord = false;
        DocumentSendRecordQueryDto documentSendRecordQueryDto = new DocumentSendRecordQueryDto();
        BeanUtils.copyProperties(queryDto, documentSendRecordQueryDto);
        documentSendRecordQueryDto.setIsSendSuccess(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
        documentSendRecordQueryDto.setSentWay(null);
        List<DocumentSendRecordVo> sendSuccessRecordList = documentSendRecordService.getDocumentSendRecordList(documentSendRecordQueryDto);
        DocumentSendRecordVo firstElectricRecord = null;
        for (DocumentSendRecordVo e : sendSuccessRecordList) {
            if (SendWayEnum.TEXT_MSG.getCode().equals(e.getSentWayId())) {
                firstElectricRecord = e;
                hadSendRecord = true;
                break;
            }
        }
        /*
        各种送达方式送达后宿主文书对应送达时间是否为空分析：
        1、电子送达
            -单当事人 【非空】
            -多当事人
                -合并处罚【所有当事人送达后才算会非空】
                -分别处罚【非空】
        2、送达登记
            -单当事人 【非空】
            -多当事人
                -合并处罚【所有当事人送达后才算会非空】
                -分别处罚【非空】
        3、当场送达
            -单当事人 【非空】
            -多当事人
                -合并处罚【所有当事人送达后才算会非空】
                -分别处罚【非空】
         */
        if (ObjectUtils.isEmpty(sentTime)) {
            //待送达
            vo.setSendStatusId(DocumentSendStatusEnum.WAIT_TO_SEND.getCode());
            vo.setSendStatusName(DocumentSendStatusEnum.WAIT_TO_SEND.getDes());
            vo.setRemaining(remaining);
            //多当事人合并处罚查看是否送达是各自的送达记录的送达时间
            String handleType = caseMainInfo.getHandleType();
            if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                    && HandleTypeEnum.MERGE_PUNISH.getCode().equals(handleType)
            ){
                if (!ObjectUtils.isEmpty(sendSuccessRecordList) && sendSuccessRecordList.size() > 0) {
                    firstRecord = sendSuccessRecordList.get(Constant.INTEGER_0);
                    vo.setSentTimeConsuming(firstRecord.getSentTimeConsuming());
                    vo.setSendStatusId(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
                    vo.setSendStatusName(DocumentSendStatusEnum.SEND_SUCCESS.getDes());
                    sentTime = firstRecord.getSentTime();
                    vo.setSentTime(sentTime);
                }
            }
        } else {
            vo.setSendStatusId(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
            vo.setSendStatusName(DocumentSendStatusEnum.SEND_SUCCESS.getDes());
            vo.setSentTime(sentTime);
            //取发送记录中，送达成功的最早的一条
            if (ObjectUtils.isEmpty(sendSuccessRecordList) || sendSuccessRecordList.size() == 0) {
                log.info("未找到送达记录 caseId:" + caseId + " documentId:" + documentId);
            }
        }
        vo.setSentDeadline(sentDeadline);
        vo.setDocumentUrl(caseDocumentRecord.getDocumentUrl());
        vo.setDocumentUrlAfterSeal(caseDocumentRecord.getDocumentUrlAfterSeal());
        vo.setDocumentUrlAfterSign(caseDocumentRecord.getDocumentUrlAfterSign());

        //文书送达流程记录信息
        List<DocumentSentFlowInfoVo> documentSentFlowInfoList = new ArrayList<>();
        //送达登记
        //获取送达登记相关信息
        DocumentSentRegisterInfoRequest request = new DocumentSentRegisterInfoRequest();
        request.setCaseId(caseId);
        request.setDocumentId(documentId);
        request.setPartyId(partyId);
        DocumentSentRegisterVo sentRegisterInfo
                = getDocumentSentRegisterInfo(request);
        vo.setDocumentSentRegisterInfo(sentRegisterInfo);

        DocumentSentFlowInfoVo documentSendFlowInfo;

        //判断是否现场送达环节
        DocumentSendRecordQueryDto querySendInfo = new DocumentSendRecordQueryDto();
        querySendInfo.setCaseId(caseId);
        querySendInfo.setDocumentId(documentId);
        querySendInfo.setPartyId(partyId);
        querySendInfo.setSentWay(SendWayEnum.LOCAL_MSG.getCode());
        List<DocumentSendRecordVo>  sendInfoList = documentSendRecordService.getDocumentSendRecordList(querySendInfo);
        DocumentSendRecordVo realPlaceSendInfo = new DocumentSendRecordVo();
        boolean hasRealPlaceSentInfo = false;
        CaseDocumentRecord sentReceiptDocInfo = new CaseDocumentRecord();
        if(!ObjectUtils.isEmpty(sendInfoList) && sendInfoList.size() > 0){
            realPlaceSendInfo = sendInfoList.get(Constant.INTEGER_0);
            hasRealPlaceSentInfo = true;
        } else {
            //查询是否有xx送达回证的现场送达
            //先获取文书id
            if(!ObjectUtils.isEmpty(sentReceiptPrintDocumentCatalogCode)){
                if(DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(documentKindCode)){
                    sentReceiptDocInfo = caseDocumentRecordService.getRelationCaseDocumentRecord(caseId, documentId);
                }else {
                    sentReceiptDocInfo = caseDocumentRecordService.getCaseDocumentRecord(caseId,sentReceiptPrintDocumentCatalogCode,partyId);
                }
                if(!ObjectUtils.isEmpty(sentReceiptDocInfo)){
                    String sentReceiptDocumentId = sentReceiptDocInfo.getId();
                    querySendInfo.setDocumentId(sentReceiptDocumentId);
                    sendInfoList = documentSendRecordService.getDocumentSendRecordList(querySendInfo);
                    if(!ObjectUtils.isEmpty(sendInfoList) && sendInfoList.size() > 0){
                        realPlaceSendInfo = sendInfoList.get(Constant.INTEGER_0);
                        hasRealPlaceSentInfo = true;

                        //遍历，判断是否有发送成功的
                        sendInfoList.forEach(e->{
                            String sendStatus = e.getSendStatusId();
                            if(DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(sendStatus)){
                                if(ObjectUtils.isEmpty(vo.getSentTime())){
                                    vo.setSentTime(e.getSentTime());
                                    vo.setSentTimeConsuming(e.getSentTimeConsuming());
                                    vo.setSendStatusId(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
                                    vo.setSendStatusName(DocumentSendStatusEnum.SEND_SUCCESS.getDes());
                                }
                            }
                        });
                    }
                }
            }
        }
        if (hasRealPlaceSentInfo) {
            //有
            String realPlaceSentType = realPlaceSendInfo.getRealPlaceSentType();
            vo.setRealPlaceSentType(realPlaceSentType);
            vo.setRealPlaceSentTypeName(RealPlaceSentTypeEnum.getValueByCode(realPlaceSentType));
            documentSendFlowInfo = new DocumentSentFlowInfoVo();
            documentSendFlowInfo.setFlowTitle("现场送达");
            String signStampedStatus = caseDocumentRecord.getDocumentSignstampedStatus();
            documentSendFlowInfo.setOperateUserName(realPlaceSendInfo.getSenderRealName());
            documentSendFlowInfo.setOperateUserId(realPlaceSendInfo.getSenderId());
            documentSendFlowInfo.setOperateTime(realPlaceSendInfo.getCreateTime());

            vo.setDocumentSignstampedStatus(YesOrNoEnum.NO.getCode());
            if (Constant.STRING_1.equals(realPlaceSentType)) {
                //原件签收
                if (DocumentStatusEnum.CONFIRM_END.getCode().equals(signStampedStatus)) {
                    //已签字
                    if (!ObjectUtils.isEmpty(sentTime)) {
                        vo.setDocumentSignstampedStatus(YesOrNoEnum.YES.getCode());
                    }
                    documentSendFlowInfo.setTitleShowTime(sentTime);
                    String realPlaceSentShowDocUrl = caseDocumentRecord.getDocumentUrlAfterSign();
                    if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                        realPlaceSentShowDocUrl = caseDocumentRecord.getDocumentUrlAfterSeal();
                        if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                            realPlaceSentShowDocUrl = caseDocumentRecord.getDocumentUrl();
                        }
                    }
                    vo.setRealPlaceSentShowDocUrl(realPlaceSentShowDocUrl);
                } else {
                    //未签字
                    String realPlaceSentShowDocUrl = caseDocumentRecord.getDocumentUrlAfterSeal();
                    if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                        realPlaceSentShowDocUrl = caseDocumentRecord.getDocumentUrl();
                    }
                    vo.setRealPlaceSentShowDocUrl(realPlaceSentShowDocUrl);
                }
            } else {
                //送达回证
                signStampedStatus = sentReceiptDocInfo.getDocumentSignstampedStatus();
                if (DocumentStatusEnum.CONFIRM_END.getCode().equals(signStampedStatus)) {
                    //已签字
                    String signStatus = sentReceiptDocInfo.getDocumentSignstampedStatus();
                    if (DocumentStatusEnum.CONFIRM_END.getCode().equals(signStatus)) {
                        vo.setDocumentSignstampedStatus(YesOrNoEnum.YES.getCode());
                    }
                    documentSendFlowInfo.setTitleShowTime(realPlaceSendInfo.getSentTime());
                    String realPlaceSentShowDocUrl = sentReceiptDocInfo.getDocumentUrlAfterSign();
                    if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                        realPlaceSentShowDocUrl = sentReceiptDocInfo.getDocumentUrlAfterSeal();
                        if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                            realPlaceSentShowDocUrl = sentReceiptDocInfo.getDocumentUrl();
                        }
                    }
                    vo.setRealPlaceSentShowDocUrl(realPlaceSentShowDocUrl);
                } else {
                    //未签字
                    String realPlaceSentShowDocUrl = sentReceiptDocInfo.getDocumentUrlAfterSeal();
                    if(ObjectUtils.isEmpty(realPlaceSentShowDocUrl)){
                        realPlaceSentShowDocUrl = sentReceiptDocInfo.getDocumentUrl();
                    }
                    vo.setRealPlaceSentShowDocUrl(realPlaceSentShowDocUrl);
                }
            }
            documentSentFlowInfoList.add(documentSendFlowInfo);
        }
        if (!ObjectUtils.isEmpty(sentRegisterInfo.getSentTime())) {
            documentSendFlowInfo = new DocumentSentFlowInfoVo();
            documentSendFlowInfo.setFlowTitle("送达登记");
            documentSendFlowInfo.setTitleShowTime(sentRegisterInfo.getSentTime());
            documentSendFlowInfo.setOperateUserName(sentRegisterInfo.getOperateUserRealName());
            documentSendFlowInfo.setOperateUserId(sentRegisterInfo.getOperateUserId());
            documentSendFlowInfo.setOperateTime(sentRegisterInfo.getCreateTime());
            documentSentFlowInfoList.add(documentSendFlowInfo);
        }
        if (hadSendRecord) {
            //电子送达
            documentSendFlowInfo = new DocumentSentFlowInfoVo();
            documentSendFlowInfo.setFlowTitle("电子送达");
            documentSendFlowInfo.setTitleShowTime(firstElectricRecord.getSentTime());
            documentSendFlowInfo.setOperateUserName(firstElectricRecord.getSenderRealName());
            documentSendFlowInfo.setOperateUserId(firstElectricRecord.getSenderId());
            documentSendFlowInfo.setOperateTime(firstElectricRecord.getCreateTime());
            documentSendFlowInfo.setReceiverTypeName(firstElectricRecord.getReceiverTypeId());
            documentSendFlowInfo.setReceiverName(firstElectricRecord.getReceiverName());
            String sentWayId = firstElectricRecord.getSentWayId();
            if (!ObjectUtils.isEmpty(sentWayId)) {
                documentSendFlowInfo.setSentWayName(SendWayEnum.getValueByCode(sentWayId));
            }

            documentSendFlowInfo.setReceiverAccount(firstElectricRecord.getReceiverAccount());
            documentSentFlowInfoList.add(documentSendFlowInfo);
        }
        vo.setDocumentSignstampedStatusName(YesOrNoEnum.getValueByCode(vo.getDocumentSignstampedStatus()));
        //文书生成
        documentSendFlowInfo = new DocumentSentFlowInfoVo();
        documentSendFlowInfo.setFlowTitle("文书生成");
        documentSendFlowInfo.setTitleShowTime(caseDocumentRecord.getDocumentCreateTime());
        documentSentFlowInfoList.add(documentSendFlowInfo);

        vo.setDocumentSentFlowInfoList(documentSentFlowInfoList);
        if(!ObjectUtils.isEmpty(sentReceiptDocInfo)){
            String sentReceiptPdfUrl = ObjectUtils.isEmpty(sentReceiptDocInfo.getDocumentUrl())?
                    sentReceiptDocInfo.getDocumentUrlBlank():sentReceiptDocInfo.getDocumentUrl();
            vo.setSentReceiptPdfUrl(sentReceiptPdfUrl);
        }
        //是否需要送达回执赋值
        String isReceipt = configBusiParamDocumentInfo.getIsReceipt();
        if (ObjectUtils.isEmpty(isReceipt)) {
            isReceipt = YesOrNoEnum.NO.getCode();
        }
        vo.setIsReceipt(isReceipt);
        vo.setIsReceiptName(YesOrNoEnum.getValueByCode(isReceipt));

        //查询电子送达送达回证信息
        CaseDocumentRecord electricSentReceiptInfo = null;
        if(DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(documentKindCode)){
            electricSentReceiptInfo = caseDocumentRecordService.getRelationCaseDocumentRecord(caseId, documentId);
        }else {
            electricSentReceiptInfo = caseDocumentRecordService.getCaseDocumentRecord(caseId, sentReceiptPrintDocumentCatalogCode, partyId);
        }
        if (!ObjectUtils.isEmpty(electricSentReceiptInfo)) {
            vo.setElectricSentDocId(electricSentReceiptInfo.getId());
            vo.setElectricSentShowDocUrl(electricSentReceiptInfo.getDocumentUrlAfterSeal());
        } else {
            vo.setElectricSentShowDocUrl((ObjectUtils.isEmpty(vo.getDocumentUrlAfterSign()) ? vo.getDocumentUrlAfterSeal() : vo.getDocumentUrlAfterSign()));
        }
        return vo;
    }

    /**
     * 描述：从文书记录信息中获取最新的文书地址
     *
     * @param recordA {@link CaseDocumentRecord}
     * @param recordB {@link CaseDocumentRecordVo}
     * @return 最新的文书地址
     * @author xiangyuyu
     * @date 2022-04-24 18:48
     */
    private String getLatestDocUrlFromDocRecord(CaseDocumentRecord recordA, CaseDocumentRecordVo recordB) {
        String url = "";
        String oriUrl = "";
        String afterSealUrl = "";
        String afterSignUrl = "";
        if (ObjectUtils.isEmpty(recordA)) {
            if (ObjectUtils.isEmpty(recordB)) {
                throw new BusinessException("未指定文书记录信息");
            } else {
                oriUrl = recordB.getDocumentUrl();
                afterSealUrl = recordB.getDocumentUrlAfterSeal();
                afterSignUrl = recordB.getDocumentUrlAfterSign();
            }
        } else {
            oriUrl = recordA.getDocumentUrl();
            afterSealUrl = recordA.getDocumentUrlAfterSeal();
            afterSignUrl = recordA.getDocumentUrlAfterSign();
        }
        url = ObjectUtils.isEmpty(afterSignUrl) ? (ObjectUtils.isEmpty(afterSealUrl) ? oriUrl : afterSealUrl) : afterSignUrl;
        return url;
    }

    /**
     * 【V1.0.0】描述：确认送达
     *
     * @param saveDto {@link ConfirmSendSaveDto}
     * @return {@link Result <String>} 送达结果
     * @author xiangyuyu
     * @date 2022-02-16 16:02
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> confirmSend(ConfirmSendSaveDto saveDto) {
        log.info("confirmSend start...saveDto:" + saveDto);
        //校验相关文书是否满足送达条件
        checkBeforeSend(saveDto);
        String sentWay = saveDto.getSentWay();
        if (!SendWayEnum.TEXT_MSG.getCode().equals(sentWay)) {
            return Result.error("目前仅支持短信送达");
        }
        String tel = saveDto.getReceiverAccount();
        String username = saveDto.getReceiverName();
        String documentId = saveDto.getDocumentId();
        String partyId = saveDto.getPartyId();
        String content = assembleSmsContentProvince(tel, username, documentId,null);
        String sendResult = sendSmsProvince(tel, content, "");
        //保存发送记录
        String caseId = saveDto.getCaseId();
        DocumentSendRecordSaveDto sendRecord = new DocumentSendRecordSaveDto();
        sendRecord.setOperateType(RecordSaveTypeEnum.ADD.getCode());
        sendRecord.setCaseId(caseId);
        sendRecord.setDocumentId(documentId);
        sendRecord.setSentWay(sentWay);
        String documentCatalogCode = saveDto.getDocumentCatalogCode();
        sendRecord.setDocumentCatalogCode(documentCatalogCode);
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
        String handleType = caseMainInfo.getHandleType();
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                    && HandleTypeEnum.MERGE_PUNISH.getCode().equals(handleType)) {
                throw new BusinessException("多当事人时送达流程指定当事人id");
            }
            Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
            partyId = map.get("partyId");
        }
        sendRecord.setPartyId(partyId);

        UserDTO userInfo = UserUtil.getUserInfo();
        if (ObjectUtils.isEmpty(userInfo)) {
            throw new BusinessException("登录失效-确认送达");
        }
        sendRecord.setSenderId(userInfo.getUserId() + "");
        sendRecord.setSenderRealName(userInfo.getRealName());
        sendRecord.setSenderContactNum(userInfo.getPhone());
        String sendStatus;
        LocalDateTime sentReceiptSentTime = null;
        if (!ObjectUtils.isEmpty(sendResult)) {
            sendRecord.setSendStatus(DocumentSendStatusEnum.SEND_FAIL.getCode());
            sendRecord.setSendFailReason(sendResult);
        } else {
            sendRecord.setSendStatus(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
            //TODO：计算送达耗时【业务非常复杂，暂不显示】
            //sendRecord.setSentTimeConsuming("x天x时3分");
            /*
            送达时间更新业务规则：
            1.电子送达 ----->x   送达登记 取电子送达的送达时间
            2.送达登记 ----->    电子送达 电子送达时（送达时间已有，不更新）取送达登记时间
            3.当场送达 ----->    电子送达 电子送达时（送达时间已有，不更新）取当场送达时间
            4.送达登记 ----->    送达登记 取送达登记的送达时间（即最新）
            5.送达登记 ----->    电子送达 ------> 送达登记 取送达登记的送达时间（即最新）
             */


            LocalDateTime now = LocalDateTime.now();
            sendRecord.setSendTime(now);
            sentReceiptSentTime = now;
            //获取该文书的sentTime
            CaseDocumentRecordVo caseDocumentRecordOri = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
            if (ObjectUtils.isEmpty(caseDocumentRecordOri) || ObjectUtils.isEmpty(caseDocumentRecordOri.getSentTime())) {
                sendRecord.setSentTime(now);
            } else {
                //sentReceiptSentTime = caseDocumentRecordOri.getSentTime();
            }
            //更新文书记录表（送达时间）
            // FIXME: 2022/3/5 后期优化，根据实际业务是否需要每次都更新送达时间
            /*sendStatus = DocumentSendStatusEnum.SEND_SUCCESS.getCode();
            caseDocumentRecordService.updateDocumentSentInfo(documentId, now, sendStatus);*/
        }
        saveDto.setSentTime(sentReceiptSentTime);
        sendRecord.setSentTime(sentReceiptSentTime);
        sendRecord.setSendContent(content);
        sendRecord.setReceiverAccount(tel);
        sendRecord.setReceiverType(saveDto.getReceiverType());
        sendRecord.setReceiverName(username);
        sendRecord.setReceiverContactNum(tel);
        //保存会发生流程滚动,在流程滚动之前先生成送达回证
        //生成电子送达对应的送达回证
        generateElectricSentReceipt(saveDto);

        documentSendRecordService.saveDocumentSendRecord(sendRecord);

        if (!ObjectUtils.isEmpty(sendResult)) {
            return Result.error(sendResult);
        }

        if (checkDocumentIsAllSend(caseId, documentId)) { //所有文书都已送达当事人
            //更新文书记录表（送达时间）
            // FIXME: 2022/3/5 后期优化，根据实际业务是否需要每次都更新送达时间
            sendStatus = DocumentSendStatusEnum.SEND_SUCCESS.getCode();
            caseDocumentRecordService.updateDocumentSentInfo(documentId, sendRecord.getSentTime(), sendStatus);
            //决定撤销
            triggerDecisionRevokeDealAfterSent(caseId, documentCatalogCode);
        }
        /*//生成电子送达对应的送达回证
        generateElectricSentReceipt(saveDto);*/
        log.info("confirmSend end...");
        // 案件中存在浙里办送达成功的文书，以后送达的文书可以在浙里办查看  // TODO 不一定需要
        Example example = new Example(CaseDocumentRecord.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("caseId",caseId).andEqualTo("documentRecordStatus",Constant.STRING_1)
                .andEqualTo("zlbService",Constant.STRING_1).andEqualTo("documentSentStatus","SEND_1");
        if (StringUtils.isNotBlank(partyId)){
            criteria.andEqualTo("partyId",partyId);
        }
        List<CaseDocumentRecord> caseDocumentRecords = caseDocumentRecordMapper.selectByExample(example);
        if (!ObjectUtils.isEmpty(caseDocumentRecords) && caseDocumentRecords.size()>0){
            CaseDocumentRecord caseDocumentRecord = caseDocumentRecords.get(0);
            CaseDocumentRecord caseDocumentRecordUpdate = new CaseDocumentRecord();
            caseDocumentRecordUpdate.setId(documentId);
            caseDocumentRecordUpdate.setZlbService(caseDocumentRecord.getZlbService());
            caseDocumentRecordUpdate.setZlbServiceTime(DateUtil.dateToLocalDateTime(new Date()));
            caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecordUpdate);
        }
        return Result.success(Constant.STRING_OPERATE_SUCCESS);
    }

    /**
     * 描述：生成电子送达对应送达回证信息
     *
     * @param dto {@link ConfirmSendSaveDto}
     * @return String 错误信息
     * @author xiangyuyu
     * @date 2022-06-20 20:13
     */
    @Override
    public String generateElectricSentReceipt(ConfirmSendSaveDto dto) {
        log.info("generateElectricSentReceipt start...dto:{}", dto);
        HashMap<String, Object> dataMap = new HashMap<>(8);
        String caseId = dto.getCaseId();
        String partyId = dto.getPartyId();
        //获取归属文书信息
        String belongDocumentId = dto.getDocumentId();
        CaseDocumentRecordVo belongDocumentInfo = caseDocumentRecordService.getCaseDocumentRecordInfo(belongDocumentId);
        String belongDocumentCatalogCode = belongDocumentInfo.getDocumentCatalogCode();
        //根据文书目录编码获取文书配置信息
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(belongDocumentCatalogCode);
        if (ObjectUtils.isEmpty(configBusiParamDocumentInfo)) {
            throw new BusinessException("未匹配到文书配置信息-documentCatalogCode：" + belongDocumentCatalogCode);
        }
        String kindName = configBusiParamDocumentInfo.getDocumentKindName();
        String kindCode = configBusiParamDocumentInfo.getDocumentKindCode();


        //根据文书目录编码获取送达回证文书目录编码 -- 优化从数据库获取
        ConfigBusiParamDocumentInfo sdhzConfig = configBusiParamDocumentInfoService.getSDHZDetailBySentDocumentCatalogCode(belongDocumentCatalogCode);
        String documentCatalogCode = sdhzConfig.getDocumentCatalogCode();

        /*if(Constant.TZ_BUSI_PARAM_ID.equals(configBusiParamDocumentInfo.getBusiParamId())){
            documentCatalogCode = Constant.TZ_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(kindCode);
        }else{
            documentCatalogCode = Constant.QS_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(kindCode);
        }*/

        String documentNumber = belongDocumentInfo.getDocumentNumber();
        //告知书送达回证特殊处理
        if (DocumentKindEnum.DOC_KIND_CFGZS.getCode().equals(kindCode)) {
            //1.送达文书名称：行政处罚事先告知书
            //2.送达文书文号：只展示文号
            //送达文书名称
            dataMap.put("SDHZ_WSMC", configBusiParamDocumentInfo.getDocumentCatalogName());
            //送达文书文号
            dataMap.put("SDHZ_WSWH", documentNumber);
        } else {
            //送达文书名称
            dataMap.put("SDHZ_WSMC", kindName);
            //送达文书文号
            dataMap.put("SDHZ_WSWH", kindName + "，" + documentNumber);
        }
        CaseMainInfo caseMainInfo=caseMainInfoMapper.selectByPrimaryKey(caseId);
        String orgStandardName = registerCommonService.getOrgStandardNameByOrgCode(caseMainInfo.getCaseOrgCode(),caseMainInfo.getCaseDeptCode());
        //办案单位标准文书抬头
        dataMap.put("SDHZ_BADW", orgStandardName);
        //受送达人：当事人，若企业展示企业名称
        String partyName = "";
        Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
        String allPartyIds = map.get("partyId");
        if (ObjectUtils.isEmpty(partyId)) {
            partyId = allPartyIds;
        }
        partyName = map.get("partyName");
        //获取该当事人的名称
        String[] idArr = allPartyIds.split(",");
        String[] nameArr = partyName.split(",");
        for (int i = 0; i < idArr.length; i++) {
            if (partyId.equals(idArr[i])) {
                partyName = nameArr[i];
            }
        }
        dataMap.put("SDHZ_SSDR", partyName);
        dataMap.put("SDHZ_SDSJ", dto.getSentTime().format(DateTimeFormatter.ofPattern(Constant.TIME_FORMAT)));

        String sendWayInfo = "电子送达，" + SendWayEnum.getValueByCode(dto.getSentWay()) + "，手机号码：" + dto.getReceiverAccount();
        dataMap.put("SDHZ_SDFS", sendWayInfo);
        //当电子送达生成送达回证时，在上下文中标记SDHZ_ELECTRON_SEND_TYPE为true。
        // 用于后续判断电子送达生成的送达回证时，不需要当事人确认
        BusinessContextUtil.set(BusinessContextKeyEnum.SDHZ_ELECTRON_SEND_TYPE, true);
        //如果是补正/更正，则使用新的方法
        if(DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(kindCode)){
            CorrectionDocSaveDetailDto detailDto = new CorrectionDocSaveDetailDto();
            detailDto.setDataMap(dataMap);
            detailDto.setPartyId(partyId);
            detailDto.setCaseId(caseId);
            detailDto.setDocumentCatalogCode(documentCatalogCode);
            //补正/更正通知书的ID
            detailDto.setRelationDocumentRecordId(dto.getDocumentId());
            //补正/更正通知书送达回证的记录ID
            detailDto.setDocumentRecordId(dto.getDocumentSendId());
            stageDocCommonOperateService.saveCorrectionConfirmSend(detailDto);
        }else {
            StageDocCommonOperateSaveDto saveDto = new StageDocCommonOperateSaveDto();
            saveDto.setDataMap(dataMap);
            saveDto.setPartyId(partyId);
            saveDto.setCaseId(caseId);
            saveDto.setDocumentCatalogCode(documentCatalogCode);
            stageDocCommonOperateService.saveDocInfo(saveDto);
        }
        log.info("generateElectricSentReceipt end");
        return "";
    }

    /**
     * 获取文书当前环节送达回证列表
     *
     * @return {@link List< String>}
     * @author: zhengqiang
     * @date: 2022/6/6
     * @param: documentId
     **/
    private List<String> getSDHZList(String documentId) {
        //查询送达回证文书编码
        List<String> SDHZList = new ArrayList<>();
        //查询文书目录编码
        CaseDocumentRecord caseDocumentRecord = caseDocumentRecordMapper.selectByPrimaryKey(documentId);
        String documentCatalogCode = caseDocumentRecord.getDocumentCatalogCode();
        //查询当前环节编码
        Example query = new Example(ConfigWorkFlowDocumentSent.class);
        query.createCriteria().andEqualTo("documentCatalogCode", documentCatalogCode);
        List<ConfigWorkFlowDocumentSent> configWorkFlowDocumentSents = configWorkFlowDocumentSentMapper.selectByExample(query);
        if (!configWorkFlowDocumentSents.isEmpty()) {
            ConfigWorkFlowDocumentSent configWorkFlowDocumentSent = configWorkFlowDocumentSents.get(0);
            //根据环节编码查询送达回证文书目录编码
            Example SDHZQuery = new Example(ConfigWorkFlowDocumentSent.class);
            SDHZQuery.createCriteria().andEqualTo("workLinkCode", configWorkFlowDocumentSent.getWorkLinkCode())
                    .andLike("documentCatalogCode", "%_" + Constant.STRING_KIND_CODE_SDHZ + "%");
            List<ConfigWorkFlowDocumentSent> SDHZDocuments = configWorkFlowDocumentSentMapper.selectByExample(SDHZQuery);
            SDHZList = SDHZDocuments.stream().map(document -> document.getDocumentCatalogCode()).collect(Collectors.toList());
        }
        return SDHZList;
    }

    /**
     * 根据案件类型校验文书是否都已送达
     *
     * @return {@link boolean}
     * @author: zhengqiang
     * @date: 2022/5/17
     * @param: caseId
     * @param: documentId
     * @return {@link boolean}
     **/
    @Override
    public boolean checkDocumentIsAllSend(String caseId, String documentId){
        boolean flag = false;
        //新增逻辑判断：
        // 1.多当事人案件,合并处罚：需要判断是否所有当事人文书都已经送达，都已送达则修改文书记录送达时间及状态
        // 2.多当事人案件,分别处罚：当前当事人文书送达则修改文书记录送达时间及状态
        // 3.单个当事人案件：当前当事人文书送达则修改文书记录送达时间及状态
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        //案件案由、当事人类型；1：单案由单当事人 2：多案由单当事人 3：单案由多当事人
        String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
        //处置方式(1-合并处罚/2-分别处罚)
        String handleType = caseMainInfo.getHandleType();
        if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType) && HandleTypeEnum.MERGE_PUNISH.getCode().equals(handleType)) {
            DocumentSendRecordByPartiesQueryDto documentSendRecordByPartiesQueryDto = new DocumentSendRecordByPartiesQueryDto(caseId, documentId);
            List<DocumentSendRecordByPartiesVo> record = documentSendRecordMapper.selectDocumentSendRecordListByPartiesOfMergePunish(documentSendRecordByPartiesQueryDto);
            /*flag = !record.stream()
                    .anyMatch(recordVo -> !DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(recordVo.getSendStatusId()));*/

            //查询送达回证文书编码
            List<String> SDHZList = getSDHZList(documentId);

            for (DocumentSendRecordByPartiesVo recordVo : record) {
                //1.判断是否有送达记录且送达成功
                if (!DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(recordVo.getSendStatusId())) {
                    //1.送达回证编码是否存在
                    if (SDHZList.isEmpty()) {
                        flag = false;
                        break;
                    }
                    //2.判断是否存在送达回证记录
                    List<DocumentSendRecordByPartiesVo> SDHZSendRecords = documentSendRecordMapper.selectDocumentSendRecordByCaseIdAndCatalogCodeAndPartyId(caseId, SDHZList, recordVo.getPartyId());
                    if (SDHZSendRecords.isEmpty()) {
                        flag = false;
                        break;
                    }
                    //2.判断送达回证记录是否送达成功
                    DocumentSendRecordByPartiesVo SDHZSendRecord = SDHZSendRecords.get(0);
                    if (!DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(SDHZSendRecord.getSendStatusId())) {
                        flag = false;
                        break;
                    }
                }

                flag = true;
            }

        }else{
            flag = true;
        }
        return flag;
    }

    /**
     * 描述：送达前提条件校验
     *
     * @author xiangyuyu
     * @date 2022-03-05 14:30
     */
    public void checkBeforeSend(ConfirmSendSaveDto saveDto) {
        String caseId = saveDto.getCaseId();
        String documentId = saveDto.getDocumentId();
        String documentCatalogCode = saveDto.getDocumentCatalogCode();
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
        String isElecSend = configBusiParamDocumentInfo.getIsElecSend();
        if (ObjectUtils.isEmpty(configBusiParamDocumentInfo)) {
            throw new BusinessException("未找到业务关联文书配置信息");
        }
        if (!YesOrNoEnum.YES.getCode().equals(isElecSend)) {
            throw new BusinessException("该文书未配置电子送达");
        }
        //查看文书是否生效
        String isApprove = configBusiParamDocumentInfo.getIsApprove();
        CaseDocumentRecordVo caseDocumentRecordInfo = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        if (YesOrNoEnum.YES.getCode().equals(isApprove)) {
            //查看终审是否通过
            String documentAuditStatus = caseDocumentRecordInfo.getDocumentAuditStatus();
            if (!"pass".equals(documentAuditStatus)) {
                throw new BusinessException("该文书未完成审批");
            }
        } else {
            //文书是否生成
            String documentUrl = caseDocumentRecordInfo.getDocumentUrl();
            if (ObjectUtils.isEmpty(documentUrl)) {
                throw new BusinessException("未生成文书");
            }
        }
        //是否需要机构签章
        String isDeptSign = configBusiParamDocumentInfo.getIsDeptSign();
        if (YesOrNoEnum.YES.getCode().equals(isDeptSign)) {
            String documentUrlAfterSeal = caseDocumentRecordInfo.getDocumentUrlAfterSeal();
            if (ObjectUtils.isEmpty(documentUrlAfterSeal)) {
                throw new BusinessException("文书还未通过机构盖章");
            }
        }
        //非办案人员不允许操作
        List<String> handlerUserIdList = new ArrayList<>();
        List<CaseHandlePersonRecordVo> caseHandlePersonRecordList
                = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
        if (!ObjectUtils.isEmpty(caseHandlePersonRecordList) && caseHandlePersonRecordList.size() > 0) {
            caseHandlePersonRecordList.forEach(e -> {
                handlerUserIdList.add(e.getHandlePersonId());
            });
        }
        UserDTO userInfo = UserUtil.getUserInfo();
        if (!ObjectUtils.isEmpty(userInfo)) {
            String userId = userInfo.getUserId() + "";
            if (!handlerUserIdList.contains(userId)) {
                throw new BusinessException("非该案件办案人员无法进行此操作");
            }
        } else {
            throw new BusinessException("登录失效-checkBeforeSend");
        }

        //已结案、已终止、已移交时不允许送达
        //4-终止，3-结案
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String caseStatus = caseMainInfo.getCaseStatus();
        String caseType = caseMainInfo.getCaseType();
        //排除简易程序
        if (!CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
            if(CaseStatusEnum.END_CASE.getCode().equals(caseStatus)) {
                //结案
                //如果存在行政处罚撤销决定书，可以送达
                ////V1.1.3结案时可以操作
//                CaseDocumentRecordDto documentInfo = caseDocumentRecordService.getCaseDocumentRecordByKindCode(caseId,Constant.STRING_KIND_CODE_XZCFCXJDS);
//                if(ObjectUtils.isEmpty(documentInfo)){
//                    throw new BusinessException("案件结案状态时无法进行此操作");
//                }
            } else if(CaseStatusEnum.TERMINATE.getCode().equals(caseStatus)) {
                //终止
                throw new BusinessException("案件终止状态时无法进行此操作");
            }
        }
    }

    /**
     * 描述：组装短信内容
     *
     * @param tel        手机号码
     * @param username   姓名
     * @param documentId 文书id
     * @author xiangyuyu
     * @date 2022-02-26 10:23
     */
    public String assembleSmsContent(String tel, String username, String documentId) {
        //获取文书相关信息
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        String documentUrl = caseDocumentRecord.getDocumentUrl();
        String documentUrlAfterSeal = caseDocumentRecord.getDocumentUrlAfterSeal();
        //String documentUrlAfterSign = caseDocumentRecord.getDocumentUrlAfterSign(); //一般都是先送达在签字的
        String fileUrl = documentUrl;
        if (!ObjectUtils.isEmpty(documentUrlAfterSeal)) {
            fileUrl = documentUrlAfterSeal;
        }

        //增加简易处罚文书地址判断逻辑
        /*CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseDocumentRecord.getCaseId());
        if (!ObjectUtils.isEmpty(caseMainInfo) && CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseMainInfo.getCaseType())) {
            //简易处罚也可以不签字
            String documentUrlAfterSign = caseDocumentRecord.getDocumentUrlAfterSign();
            if (!ObjectUtils.isEmpty(documentUrlAfterSign)) {
                fileUrl = documentUrlAfterSign;
            }
        }*/

        //获取当前登录用户的信息
        UserDTO userInfo = UserUtil.getUserInfo();
        String handleOrgName = "";
        if (!ObjectUtils.isEmpty(userInfo)) {
            handleOrgName = userInfo.getOrgName();
        }
        String content = username + "，您好：" + handleOrgName + "向您送达" + caseDocumentRecord.getDocumentNumber() + "相关文书，请点此链接查看" + fileUrl;
        log.info(content);
        return content;
    }


    /**
     * 描述：组装短信内容-省级
     *
     * @param tel        手机号码
     * @param username   姓名
     * @param documentId 文书id
     * @param smsType 消息类型
     * @author xiangyuyu
     * @date 2022-02-26 10:23
     */
    public String assembleSmsContentProvince(String tel, String username, String documentId,String smsType) {
        //获取文书相关信息
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        String documentCatalogCode = caseDocumentRecord.getDocumentCatalogCode();
        String caseId = caseDocumentRecord.getCaseId();
        CaseMainInfoVo caseMainInfoVo = caseMainInfoService.getCaseMainInfo(caseId);
        //查询文书种类
        List<ConfigBusiParamDocumentInfo> configList = configBusiParamDocumentInfoService.getDocumentConfigInfoByDocumentCatalogCode(caseId, caseMainInfoVo, documentCatalogCode);
        String kindCode;
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo;
        if (!ObjectUtils.isEmpty(configList)) {
            configBusiParamDocumentInfo = configList.get(Constant.INTEGER_0);
            kindCode = configBusiParamDocumentInfo.getDocumentKindCode();
        } else {
            throw new BusinessException("未匹配文书种类编码信息-caseId:" + caseId + ",documentCatalogCode:" + documentCatalogCode);
        }
        //行政执法单位名称
        String oriOrgName = caseMainInfoVo.getCaseOrgName();
        String orgName = "【" + oriOrgName + "】";
        //案件名称(取消直接取值，使用案由表中的illegalDetailFormat)
        //String caseName = caseMainInfoVo.getCaseName();
        //获取案由信息
        String caseReasonName = "";
        Example example = new Example(CaseReasonMainRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("status", Constant.STRING_1);
        List<CaseReasonMainRecord> caseReasonMainRecords = caseReasonMainRecordMapper.selectByExample(example);
        if (!ObjectUtils.isEmpty(caseReasonMainRecords)) {
            if (caseReasonMainRecords.size() == 1) {
                caseReasonName = BaseUtil.handleCaseReason(caseReasonMainRecords.get(0).getCaseReasonName() + "案");
            } else {
                caseReasonName = BaseUtil.handleCaseReason(caseReasonMainRecords.get(0).getCaseReasonName()) + "等" + caseReasonMainRecords.size() + "项违法行为案";
            }
        }
        //xx文书做出时间
        LocalDateTime time = caseDocumentRecord.getDocumentApprovalTime();
        if (ObjectUtils.isEmpty(time)) {
            time = caseDocumentRecord.getDocumentCreateTime();
        }
        String timeStr = time.format(DateTimeFormatter.ofPattern(Constant.TIME_FORMAT));
        //xx文号
        String documentNumber = caseDocumentRecord.getDocumentNumber();
        //xx文书地址
        String documentUrl = caseDocumentRecord.getDocumentUrl();
        String documentUrlAfterSeal = caseDocumentRecord.getDocumentUrlAfterSeal();
        //String documentUrlAfterSign = caseDocumentRecord.getDocumentUrlAfterSign(); //一般都是先送达在签字的
        String fileUrl = documentUrl;
        if (!ObjectUtils.isEmpty(documentUrlAfterSeal)) {
            fileUrl = documentUrlAfterSeal;
        }

        //申辩时间期限
        String objectionDays = configBusiParamDocumentInfo.getObjectionDays();
        if (ObjectUtils.isEmpty(objectionDays)) {
            objectionDays = Constant.STRING_3;
        }
        if (Constant.STRING_KIND_CODE_CFGZS.equals(kindCode) || Constant.STRING_KIND_CODE_DK2BYXZCFGZS.equals(kindCode)) {
            if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(caseMainInfoVo.getCasePartiesReasonType())
                    && HandleTypeEnum.PART_PUNISH.getCode().equals(caseMainInfoVo.getHandleType())) {
                Example auxiliaryExample = new Example(CaseMainDetailAuxiliaryInfo.class);
                auxiliaryExample.createCriteria().andEqualTo("caseId", caseId).andEqualTo("partyId", caseDocumentRecord.getPartyId());
                List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos = caseMainDetailAuxiliaryInfoMapper.selectByExample(auxiliaryExample);
                if (ObjectUtil.isNotEmpty(caseMainDetailAuxiliaryInfos)) {
                    Integer punishBeforeInformPeriod = caseMainDetailAuxiliaryInfos.get(0).getPunishBeforeInformPeriod();
                    if (ObjectUtil.isNotEmpty(punishBeforeInformPeriod)) {
                        objectionDays = "" + punishBeforeInformPeriod;
                    }
                }
            } else {
                CaseMainDetailInfo caseMainDetailInfo = caseMainDetailInfoMapper.selectByPrimaryKey(caseId);
                if (ObjectUtil.isNotEmpty(caseMainDetailInfo)) {
                    Integer punishBeforeInformPeriod = caseMainDetailInfo.getPunishBeforeInformPeriod();
                    if (ObjectUtil.isNotEmpty(punishBeforeInformPeriod)) {
                        objectionDays = "" + punishBeforeInformPeriod;
                    }
                }
            }
        }

        //获取机构信息
        SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCode(caseMainInfoVo.getCaseOrgCode(),caseMainInfoVo.getCaseDeptCode());
        //复议机构
        String administrativeOrgName = sysDepartParam.getAdministrativeGovName();
        //诉讼机构
        String administrativeActionCourtName = sysDepartParam.getAdministrativeActionCourtName();
        String orgTel = sysDepartParam.getPhone();

        String content;
        if (ObjectUtils.isEmpty(oriOrgName)) {
            throw new BusinessException("未配置机构名称，请联系管理员！");
        }
        if (Constant.STRING_1.equals(smsType)) {
            //【xxxxxxx】通知，请你进入浙里办-搜索-执法监管专区-文书送达签字，或点下方链接，填写与案件相关文书的送达地址
            content = orgName + "通知，请你进入浙里办-搜索-执法监管专区-文书确认，填写与案件相关文书的送达地址。";
            return content;
        } else if (Constant.STRING_2.equals(smsType)){
            content = orgName + "通知，请你进入浙里办-搜索-执法监管专区-文书确认，签署《"+ configBusiParamDocumentInfo.getDocumentCatalogName()+"》。";
            return content;
        }
        if (Constant.STRING_KIND_CODE_CFGZS.equals(kindCode)) {
            //事先告知书
            //{行政执法单位名称}{当事人名称}你好，你（单位）涉嫌{案件名称}一案现已调查完毕，现向你（单位）送达{行政执法单位名称}于{告知书作出时间}作出的行政处罚告知书{文号}{告知书地址链接}，请查收。如要求陈述或申辩，请你在收到本告知书之日起{3}日内向{行政执法单位名称}提出。
            content = orgName + username + "你好，你（单位）涉嫌" + caseReasonName + "一案现已调查完毕，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的行政处罚告知书" + documentNumber + fileUrl + "，请查收。如要求陈述或申辩，请你在收到本告知书之日起" + objectionDays + "日内向" + oriOrgName + "提出。";
        } else if (Constant.STRING_KIND_CODE_CFGZSTZL.equals(kindCode)) {
            //听证告知书
            //{行政执法单位名称}{当事人名称}你好，你（单位）涉嫌{案件名称}一案现已调查完毕，现向你（单位）送达{行政执法单位名称}于{告知书作出时间}作出的行政处罚告知书{文号}{告知书地址链接}，请查收。如要求陈述或申辩，请你在收到本告知书之日起{3}日内向{行政执法单位名称}提出。如你（单位）要求举行听证，应在收到本告知书后5个工作日内提出，逾期视为放弃听证权利
            content = orgName + username + "你好，你（单位）涉嫌" + caseReasonName + "一案现已调查完毕，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的行政处罚告知书" + documentNumber + fileUrl + "，请查收。如要求陈述或申辩，请你在收到本告知书之日起" + objectionDays + "日内向" + oriOrgName + "提出。如你（单位）要求举行听证，应在收到本告知书后5个工作日内提出，逾期视为放弃听证权利。";
        } else if (Constant.STRING_KIND_CODE_CFJDS.equals(kindCode)) {
            //决定书
            //{行政执法单位名称}{当事人名称}你好，现向你（单位）送达{行政执法单位名称}于{告知书作出时间}作出的{案件名称}一案行政处罚决定书{文号}{决定书地址链接}，请查收。如不服处罚决定的，可依法在收到之日起60日内向{复议机关}申请行政复议，或者在收到之日起六个月内向{诉讼机关}提起行政诉讼。
            if (ObjectUtils.isEmpty(administrativeOrgName)) {
                throw new BusinessException("未配置复议机构，请联系管理员！");
            }
            if (ObjectUtils.isEmpty(administrativeActionCourtName)) {
                throw new BusinessException("未配置诉讼机构，请联系管理员！");
            }
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的" + caseReasonName + "一案行政处罚决定书" + documentNumber + fileUrl + "，请查收。如不服处罚决定的，可依法在收到之日起60日内向" + administrativeOrgName + "申请行政复议，或者在收到之日起六个月内向" + administrativeActionCourtName + "提起行政诉讼。";
        } else if (Constant.STRING_KIND_CODE_XZJDLXCGS.equals(kindCode)) {
            //催告书
            //{行政执法单位名称}{当事人名称}你好，现向你（单位）送达{行政执法单位名称}于{催告书作出时间}作出的你（单位）{案件名称}一案催告书{文号}{催告书地址链接}，请查收。
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的你（单位）" + caseReasonName + "一案催告书" + documentNumber + fileUrl + "，请查收。";
        } else if (Constant.STRING_KIND_CODE_JYCXCFJDS.equals(kindCode)) {
            //简易处罚决定书
            //{行政执法单位名称}{当事人名称}你好，现向你（单位）送达{行政执法单位名称}于{告知书作出时间}作出的{案件名称}一案行政处罚决定书{文号}{决定书地址链接}，请查收。如不服处罚决定的，可依法在收到之日起60日内向{复议机关}申请行政复议，或者在收到之日起六个月内向{诉讼机关}提起行政诉讼。
            if (ObjectUtils.isEmpty(administrativeOrgName)) {
                throw new BusinessException("未配置复议机构，请联系管理员！");
            }
            if (ObjectUtils.isEmpty(administrativeActionCourtName)) {
                throw new BusinessException("未配置诉讼机构，请联系管理员！");
            }
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的" + caseReasonName + "一案行政处罚决定书" + documentNumber + fileUrl + "，请查收。如不服处罚决定的，可依法在收到之日起60日内向" + administrativeOrgName + "申请行政复议，或者在收到之日起六个月内向" + administrativeActionCourtName + "提起行政诉讼。";
        } else if (Constant.STRING_KIND_CODE_BYCFJDS.equals(kindCode)) {
            //不予处罚决定书
            //{行政执法单位名称}{当事人名称}你好，现向你（单位）送达{行政执法单位名称}于{不予处罚决定书作出时间}作出的{案件名称}一案不予行政处罚决定书{文号}{决定书地址链接}，请查收。如不服不予处罚决定的，可依法在收到之日起60日内向{复议机关}申请行政复议，或者在收到之日起六个月内向{诉讼机关}提起行政诉讼。
            if (ObjectUtils.isEmpty(administrativeOrgName)) {
                throw new BusinessException("未配置复议机构，请联系管理员！");
            }
            if (ObjectUtils.isEmpty(administrativeActionCourtName)) {
                throw new BusinessException("未配置诉讼机构，请联系管理员！");
            }
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的" + caseReasonName + "一案行政处罚决定书" + documentNumber + fileUrl + "，请查收。如不服不予处罚决定的，可依法在收到之日起60日内向" + administrativeOrgName + "申请行政复议，或者在收到之日起六个月内向" + administrativeActionCourtName + "提起行政诉讼。";
        } else if (Constant.STRING_KIND_CODE_XZCFCXJDS.equals(kindCode)) {
            //撤销处罚决定书
            // {行政执法单位名称}{当事人名称}你好，现向你（单位）送达{行政执法单位名称}于{撤销处罚决定作出时间}作出的{案件名称}一案撤销行政处罚决定决定书{文号}{决定书地址链接}，请查收。如需帮助，请联系{行政执法单位名称}办公电话：{办案机构对外办公电话号码}。
            if (ObjectUtils.isEmpty(orgTel)) {
                throw new BusinessException("未配置单位联系电话，请联系管理员！");
            }
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的" + caseReasonName + "一案行政处罚决定书" + documentNumber + fileUrl + "，请查收。如需帮助，请联系" + administrativeOrgName + "办公电话：" + orgTel;
        } else if (Constant.STRING_KIND_CODE_DK2BYXZCFGZS.equals(kindCode)) {
            //{行政执法单位名称}{当事人名称}你好，你（单位）涉嫌{案件名称}一案现已调查完毕，现向你（单位）送达{行政执法单位名称}于{告知书作出时间}作出的不予行政处罚告知书{文号}{告知书地址链接}，请查收。如要求陈述或申辩，请你在收到本告知书之日起{3}日内向{行政执法单位名称}提出。
            content = orgName + username + "你好，你（单位）涉嫌" + caseReasonName + "一案现已调查完毕，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的不予行政处罚告知书" + documentNumber + fileUrl + "，请查收。如要求陈述或申辩，请你在收到本告知书之日起" + objectionDays + "日内向" + oriOrgName + "提出。";
        } else {
            // {行政执法单位名称}{当事人名称}，你好：现向你（单位）送达{行政执法单位名称}于{文书作出时间}作出的{文书抬头}{文号}，请点此链接查看{文书地址链接}，请查收。//文书抬头？产品提供的模板存疑，先去掉。
            content = orgName + username + "你好，现向你（单位）送达" + oriOrgName + "于" + timeStr + "作出的" + documentNumber + "请点此链接查看" + fileUrl + "，请查收。";
        }
        log.info(content);
        return content;
    }

    /**
     * 描述：处理案件名称
     *
     * @param caseName 处理前案件名称
     * @return String 案件名称
     * @author xiangyuyu
     * @date 2022/9/5
     * @since v1.4.1
     */
    private String dealCaseName(String caseName) {
        return caseName;
    }


    /**
     * 【V2.0.0】描述：获取电子送达页面送达人初始化信息
     *
     * @param request {@link DocumentSentAddressInfoRequest}
     * @return {@link Result<CaseDocumentSendinfoConfirmVo>} 电子送达页面送达人初始化信息
     * @author xiangyuyu
     * @date 2022-02-28 15:58
     */
    @Override
    public CaseDocumentSendinfoConfirmVo getReceiverInitInfo(DocumentSentAddressInfoRequest request) {
        return documentSendinfoConfirmService.getCaseDocumentSendInfoConfirmInfo(request);
    }

    /**
     * 【V1.1.0】描述：获取送达回证文书地址
     *
     * @param queryDto {@link SentReceiptDocQueryDto}
     * @return String 送达回证文书地址
     * @author xiangyuyu
     * @dque 2022-04-20 14:40
     */
    @Override
    public String getSentReceiptDocUrl(SentReceiptDocQueryDto queryDto) {
        String documentCatalogCode = queryDto.getDocumentCatalogCode();
        //查看是否有生成过空白文书
        String caseId = queryDto.getCaseId();
        String isGetBlankDoc = queryDto.getIsGetBlankDoc();
        String url;
        String partyId = queryDto.getPartyId();
        String partyName = "";
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
            String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
            if (ObjectUtils.isEmpty(partyId)) {
                if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                    throw new BusinessException("多当事人时送达流程指定当事人id");
                }
            }
        }
        Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
        String allPartyIds = map.get("partyId");
        if(ObjectUtils.isEmpty(partyId)){
            partyId  = allPartyIds;
        }
        partyName = map.get("partyName");
        //获取该当事人的名称
        String[] idArr = allPartyIds.split(",");
        String[] nameArr = partyName.split(",");
        for (int i = 0; i < idArr.length; i++) {
            if(partyId.equals(idArr[i])){
                partyName = nameArr[i];
            }
        }
        CaseDocumentRecord vo = caseDocumentRecordService.getCaseDocumentRecord(caseId, documentCatalogCode,partyId);
        if (YesOrNoEnum.YES.getCode().equals(isGetBlankDoc)) {
            boolean hasBlankReceiptDoc = true;
            if (ObjectUtils.isEmpty(vo)) {
                hasBlankReceiptDoc = false;
            } else {
                url = vo.getDocumentUrlBlank();
                if(ObjectUtils.isEmpty(url)){
                    hasBlankReceiptDoc = false;
                }
            }
            if (!hasBlankReceiptDoc) {
                StageDocCommonOperateSaveDto saveDto = new StageDocCommonOperateSaveDto();
                BeanUtils.copyProperties(queryDto, saveDto);
                HashMap<String, Object> dataMap = new HashMap<>(8);

                if (!ObjectUtils.isEmpty(vo)) {
                    String documentContent = vo.getDocumentContent();
                    dataMap = JSON.parseObject(documentContent, HashMap.class);
                } else {
                    //初次生成
                    //获取归属文书信息
                    CaseDocumentRecordVo belongDocumentInfo = caseDocumentRecordService.getCaseDocumentRecordInfo(queryDto.getBelongDocumentId());
                    String belongDocumentCatalogCode = belongDocumentInfo.getDocumentCatalogCode();
                    //根据文书目录编码获取文书配置信息
                    ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                            = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(belongDocumentCatalogCode);
                    if (ObjectUtils.isEmpty(configBusiParamDocumentInfo)) {
                        throw new BusinessException("未匹配到文书配置信息-documentCatalogCode：" + belongDocumentCatalogCode);
                    }
                    String kindName = configBusiParamDocumentInfo.getDocumentKindName();
                    CaseMainInfo caseMainInfo=caseMainInfoMapper.selectByPrimaryKey(caseId);
                    String orgStandardName = registerCommonService.getOrgStandardNameByOrgCode(caseMainInfo.getCaseOrgCode(),caseMainInfo.getCaseDeptCode());
                    //办案单位标准文书抬头
                    dataMap.put("SDHZ_BADW", orgStandardName);
                    //送达文书名称
                    dataMap.put("SDHZ_WSMC", kindName);
                    String documentNumber = belongDocumentInfo.getDocumentNumber();
                    //送达文书文号
                    dataMap.put("SDHZ_WSWH",  documentNumber);
                    //受送达人：当事人，若企业展示企业名称
                    dataMap.put("SDHZ_SSDR", partyName);
                    //主办人签名
                    dataMap.put("mainHandleSignPic", "/");
                    //协办人签名
                    dataMap.put("assistHandleSignPic", "/");
                }
                saveDto.setDataMap(dataMap);
                saveDto.setPartyId(partyId);
                stageDocCommonOperateService.saveDocInfo(saveDto);
                CaseDocumentRecord tmpVo = caseDocumentRecordService.getCaseDocumentRecord(caseId, documentCatalogCode,partyId);
                url = tmpVo.getDocumentUrlBlank();
            } else {
                url = vo.getDocumentUrlBlank();
            }
        } else {
            url = vo.getDocumentUrl();
        }
        return url;
    }

    /**
     * 【V1.1.0】描述：现场送达状态标记
     *
     * @param saveDto {@link RealPlaceSentInfoSaveDto}
     * @return Map<String,Object> 操作结果
     * @author xiangyuyu
     * @dque 2022-04-24 16:08
     */
    @Override
    @Transactional(rollbackFor = {Error.class, Exception.class})
    public Map<String, Object> signRealPlaceSentInfo(RealPlaceSentInfoSaveDto saveDto) {
        String dataSource = saveDto.getDataSource();
        if(ApiVisitDataSourceEnum.PUNISH_MOBILE.getId().equals(dataSource)){
            return appDocumentSentFlowService.signRealPlaceSentInfo(saveDto);
        }
        Map<String, Object> resultMap = new HashMap<>(20);
        CaseDocumentRecord caseDocumentRecord = new CaseDocumentRecord();
        BeanUtils.copyProperties(saveDto, caseDocumentRecord);
        //当前阶段当场送达的文书id列表
        Set<String> idList = new HashSet<>();
        String id = saveDto.getDocumentId();
        idList.add(id);
        caseDocumentRecord.setId(id);
        UserDTO userInfo = UserUtil.getUserInfo();
        if (ObjectUtils.isEmpty(userInfo)) {
            throw new BusinessException("signRealPlaceSentInfo-登录失效");
        }
        //现场送达状态（0-待确认/1-已确认/2-取消）
        String realPlaceSentStatus = saveDto.getRealPlaceSentStatus();
        //查询是否已有对应文书记录
        CaseDocumentRecordVo record = caseDocumentRecordService.getCaseDocumentRecordInfo(id);
        //宿主文书的文书目录编码
        String documentCatalogCode = record.getDocumentCatalogCode();
        //宿主文书配置信息
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
        String documentKindCode = configBusiParamDocumentInfo.getDocumentKindCode();
        String caseId = record.getCaseId();
        //查看处置方式
        CaseMainInfoVo caseMainInfoVo = caseMainInfoService.getCaseMainInfo(caseId);
        String partyId = saveDto.getPartyId();
        String partyName = "";
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            String casePartiesReasonType = caseMainInfoVo.getCasePartiesReasonType();
            if (ObjectUtils.isEmpty(partyId)) {
                if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                    throw new BusinessException("多当事人时送达流程指定当事人id");
                }
            }
        }
        Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
        String allPartyIds = map.get("partyId");
        if(ObjectUtils.isEmpty(partyId)){
            partyId  = allPartyIds;
        }
        partyName = map.get("partyName");
        //获取该当事人的名称
        String[] idArr = allPartyIds.split(",");
        String[] nameArr = partyName.split(",");
        for (int i = 0; i < idArr.length; i++) {
            if(partyId.equals(idArr[i])){
                partyName = nameArr[i];
            }
        }
        String handleType = caseMainInfoVo.getHandleType();
        //获取当事人信息
        //TODO:后面测试无误后再删除
        /*List<CasePartiesRecordVo> casePartiesRecordList = casePartiesRecordService.getCasePartiesInfo(caseId);
        CasePartiesRecordVo casePartiesRecord = new CasePartiesRecordVo();
        if (HandleTypeEnum.PART_PUNISH.getCode().equals(handleType)) {
            //分别处罚时需要传入指定当事人id
            if (ObjectUtils.isEmpty(partyIstageDocCommonOperateServiced)) {
                throw new BusinessException("未指定当事人id");
            } else {
                //获取改当事人的相关信息
                for (CasePartiesRecordVo e : casePartiesRecordList) {
                    String tmpPartyId = e.getPartyId();
                    if (partyId.equals(tmpPartyId)) {
                        casePartiesRecord = e;
                        break;
                    }
                }

            }
        } else {
            //缺省处罚或者合并处罚只取最新录入的当事人信息
            casePartiesRecord = casePartiesRecordList.get(Constant.INTEGER_0);
        }*/
        //非办案人员不允许操作
        List<String> handlerUserIdList = new ArrayList<>();
        List<CaseHandlePersonRecordVo> caseHandlePersonRecordList
                = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
        if (!ObjectUtils.isEmpty(caseHandlePersonRecordList) && caseHandlePersonRecordList.size() > 0) {
            caseHandlePersonRecordList.forEach(e -> {
                handlerUserIdList.add(e.getHandlePersonId());
            });
        }
        if (!ObjectUtils.isEmpty(userInfo)) {
            String userId = userInfo.getUserId() + "";
            if (!handlerUserIdList.contains(userId)) {
                throw new BusinessException("非该案件办案人员无法进行此操作");
            }
        } else {
            throw new BusinessException("登录失效-checkBeforeSend");
        }
        //已结案、已终止、已移交时不允许送达
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String caseStatus = caseMainInfo.getCaseStatus();
        String caseType = caseMainInfo.getCaseType();
        if (!CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
            if(CaseStatusEnum.END_CASE.getCode().equals(caseStatus)) {
                //结案
                //如果存在行政处罚撤销决定书，可以送达
                //V1.1.3结案时可以操作
//                CaseDocumentRecordDto documentInfo = caseDocumentRecordService.getCaseDocumentRecordByKindCode(caseId,Constant.STRING_KIND_CODE_XZCFCXJDS);
//                if(ObjectUtils.isEmpty(documentInfo)){
//                    throw new BusinessException("案件结案状态时无法进行此操作");
//                }
            } else if(CaseStatusEnum.TERMINATE.getCode().equals(caseStatus)) {
                //终止
                throw new BusinessException("案件终止状态时无法进行此操作");
            }
        }

        String realPlaceSentStatusOri = null;
        String realPlaceSentType = saveDto.getRealPlaceSentType();
        //根据文书id和当场送达类型结合查询文书发送记录
        DocumentSendRecordQueryDto queryDto = new DocumentSendRecordQueryDto();
        queryDto.setCaseId(caseId);

        queryDto.setSentWay(SendWayEnum.LOCAL_MSG.getCode());
        queryDto.setRealPlaceSentType(realPlaceSentType);

        //缺省是原件签收的documentId
        if (RealPlaceSentTypeEnum.SDHZ.getCode().equals(realPlaceSentType)) {
            //要取到原件对应送达回证的文书记录id
            //根据文书目录编码获取送达回证文书目录编码 -- 优化从数据库获取
            ConfigBusiParamDocumentInfo sdhzConfig = configBusiParamDocumentInfoService.getSDHZDetailBySentDocumentCatalogCode(documentCatalogCode);
            String sentReceiptPrintDocumentCatalogCode = sdhzConfig.getDocumentCatalogCode();

            CaseDocumentRecord caseDocumentRecordReceipt = null;
            //判断是否为补正/更正的送达回证
            if(DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(documentKindCode)){
                caseDocumentRecordReceipt = caseDocumentRecordService.getRelationCaseDocumentRecord(caseId, saveDto.getDocumentId());
            }else {
                //后台直接从系统中去，不依赖前端传值 20220810
                /*String sentReceiptPrintDocumentCatalogCode = Constant.TZ_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(documentKindCode);
                if (Constant.QS_BUSI_PARAM_ID.equals(configBusiParamDocumentInfo.getBusiParamId())) {
                    sentReceiptPrintDocumentCatalogCode = Constant.QS_KIND_CODE_RELATED_SENT_RECEIPT_DOCUMENT_CATALOG_CODE_MAP.get(documentKindCode);
                }*/
                if (ObjectUtils.isEmpty(sentReceiptPrintDocumentCatalogCode)) {
                    throw new BusinessException("未匹配到送达文书对应送达回证文书目录编码配置信息");
                }
                caseDocumentRecordReceipt = caseDocumentRecordService.getCaseDocumentRecord(caseId, sentReceiptPrintDocumentCatalogCode,partyId);
                if (ObjectUtils.isEmpty(caseDocumentRecordReceipt)) {
                    throw new BusinessException("未找到送达回证文书记录-caseId:" + caseId + ",sentReceiptPrintDocumentCatalogCode:" + sentReceiptPrintDocumentCatalogCode);
                }
            }
            id = caseDocumentRecordReceipt.getId();
            idList.add(id);
            caseDocumentRecord.setId(id);
            //送达回证的送达时，用送达回证的文书目录编码赋值原先documentCatalogCode
            documentCatalogCode = sentReceiptPrintDocumentCatalogCode;
        } else {
            //原件签收增加操作限制
            //是否需要送达回执赋值为是时，当场送达只有送达回证，不允许原件签收
            String isReceipt = configBusiParamDocumentInfo.getIsReceipt();
            if (!ObjectUtils.isEmpty(isReceipt) && YesOrNoEnum.YES.getCode().equals(isReceipt)) {
                throw new BusinessException("该文书不支持当场送达-原件签收");
            }
            //获取送达回证的文书id
            String sentReceiptPrintDocumentCatalogCode = saveDto.getSentReceiptPrintDocumentCatalogCode();
            if(!ObjectUtils.isEmpty(sentReceiptPrintDocumentCatalogCode)){
                CaseDocumentRecord documentRecord = caseDocumentRecordService.getCaseDocumentRecord(caseId,sentReceiptPrintDocumentCatalogCode);
                if(!ObjectUtils.isEmpty(documentRecord)){
                    idList.add(documentRecord.getId());
                }
            }
        }
        queryDto.setDocumentId(id);
        if(!ObjectUtils.isEmpty(partyId)){
            queryDto.setPartyId(partyId);
        }
        List<DocumentSendRecordVo> sendRecordList = documentSendRecordService.getDocumentSendRecordList(queryDto);
        DocumentSendRecordVo sendRecord = null;
        if (ObjectUtils.isEmpty(sendRecordList) || sendRecordList.size() == 0) {
            //无记录，仅支持新增"待确认"状态的记录
            if (!Constant.STRING_0.equals(realPlaceSentStatus)) {
                throw new BusinessException("暂无当场送达记录，请先标记待确认记录");
            }
        } else {
            //有当场送达记录（包含已确认、待确认）
            //取第一条记录
            sendRecord = sendRecordList.get(Constant.INTEGER_0);
            realPlaceSentStatusOri = sendRecord.getRealPlaceSentStatus();
        }

        LocalDateTime sentTime = record.getSentTime();
        DocumentSendRecordSaveDto sendInfo = new DocumentSendRecordSaveDto();
        sendInfo.setDocumentCatalogCode(documentCatalogCode);

        String activePartyId = partyId;
        String activePartyName = partyName;
        //清空现场送达记录脚本抽取
        Map<String,String> deleteMap = new HashMap<>(8);
        deleteMap.put("caseId",caseId);
        deleteMap.put("isDelete",YesOrNoEnum.NO.getCode());
        deleteMap.put("partyId",activePartyId);
        deleteMap.put("sentWay",SendWayEnum.LOCAL_MSG.getCode());
        if (Constant.STRING_0.equals(realPlaceSentStatus)) {
            if (Constant.STRING_0.equals(realPlaceSentStatusOri)) {
                //throw new BusinessException("请勿重复操作");
            } else if (Constant.STRING_1.equals(realPlaceSentStatusOri)) {
                throw new BusinessException("已完成签字确认，无法完成该操作");
            }
            //清空现场送达记录 // FIXME: 2022/5/16  如果主办协办同时间点操作会有误删的情形。
            idList.forEach(e->{
                deleteMap.put("documentId",e);
                documentSendRecordService.deleteRecordBySpecialCondition(deleteMap);
            });

            //新增发送记录表内容
            sendInfo.setOperateType(RecordSaveTypeEnum.ADD.getCode());
            sendInfo.setCaseId(caseId);
            sendInfo.setDocumentId(id);
            sendInfo.setSentWay(SendWayEnum.LOCAL_MSG.getCode());
            //sendInfo.setSendTime(LocalDateTime.now());
            sendInfo.setSenderId(userInfo.getUserId() + "");
            sendInfo.setSenderRealName(userInfo.getRealName());
            //待发送
            sendInfo.setSendStatus(DocumentSendStatusEnum.WAIT_TO_SEND.getCode());
            sendInfo.setReceiverAccount(activePartyName);
            sendInfo.setReceiverType("当事人");
            sendInfo.setReceiverName(activePartyName);
            sendInfo.setPartyId(activePartyId);
            sendInfo.setRealPlaceSentType(realPlaceSentType);
            sendInfo.setRealPlaceSentStatus(realPlaceSentStatus);
            sendInfo.setIsSentRegister(YesOrNoEnum.NO.getCode());
            sendInfo.setPartyId(partyId);
            documentSendRecordService.saveDocumentSendRecord(sendInfo);

        } else if (Constant.STRING_1.equals(realPlaceSentStatus)) {
            if (Constant.STRING_1.equals(realPlaceSentStatusOri)) {
                throw new BusinessException("请勿重复操作");
            } else if (ObjectUtils.isEmpty(realPlaceSentStatusOri)) {
                throw new BusinessException("该文书暂未标记'待确认'");
            }
            sendInfo.setOperateType(RecordSaveTypeEnum.MOD.getCode());
            sendInfo.setId(sendRecord.getId());
            //更新发送记录表的送达时间、送达状态、现场送达状态
            sendInfo.setSentTime(LocalDateTime.now());
            sendInfo.setSendStatus(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
            sendInfo.setRealPlaceSentStatus(YesOrNoEnum.YES.getCode());
            documentSendRecordService.saveDocumentSendRecord(sendInfo);
            //更新送达时间
            if (ObjectUtils.isEmpty(sentTime)) {
                caseDocumentRecord.setSentTime(LocalDateTime.now());
                //更新文书记录表的送达状态、签字确认状态
                caseDocumentRecord.setDocumentSignstampedStatus(DocumentStatusEnum.CONFIRM_END.getCode());
                caseDocumentRecord.setDocumentSentStatus(DocumentStatusEnum.SENT.getCode());
                if (HandleTypeEnum.MERGE_PUNISH.getCode().equals(handleType)) {
                    if (checkDocumentIsAllSend(caseId, saveDto.getDocumentId())) {
                        caseDocumentRecord.setPartyId(null);
                        caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
                    }
                } else {
                    if (checkDocumentIsAllSend(caseId, saveDto.getDocumentId())) {
                        caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
                    }
                }
            }
            if (documentSentFlowService.checkDocumentIsAllSend(caseId, saveDto.getDocumentId())) {
                //决定撤销
                triggerDecisionRevokeDealAfterSent(caseId,documentCatalogCode);
            }
        } else if (Constant.STRING_2.equals(realPlaceSentStatus)) {
            //清空
            if (ObjectUtils.isEmpty(realPlaceSentStatusOri)) {
                resultMap.put("success", "true");
                resultMap.put("msg", "成功！");
                documentSendRecordService.saveDocumentSendRecord(sendInfo);
                return resultMap;
            } else {
                deleteMap.put("realPlaceSentType",realPlaceSentType);
                deleteMap.put("documentId",id);
                documentSendRecordService.deleteRecordBySpecialCondition(deleteMap);
            }
        } else {
            throw new BusinessException("请指定合法的现场送达状态（0-待确认/1-已确认/2-取消）");
        }
        if (DocumentStatusEnum.CONFIRM_END.getCode().equals(caseDocumentRecord.getDocumentSignstampedStatus())) {
            //判断是否是送达回证
            if (RealPlaceSentTypeEnum.SDHZ.getCode().equals(realPlaceSentType)) {
                //更新宿主文书在文书记录表中的送达时间
                caseDocumentRecord.setId(saveDto.getDocumentId());
                //原件的签字捺印状态不做更新
                caseDocumentRecord.setDocumentSignstampedStatus(null);
                if(ObjectUtils.isEmpty(partyId)){
                    caseDocumentRecord.setPartyId(null);
                }
                if (documentSentFlowService.checkDocumentIsAllSend(caseId, saveDto.getDocumentId())) {
                    caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
                }
            }
            /*resultMap.put("workSubId",partyId);
            resultMap.put("closeSignal", "CLOSE-TRIGGER-SENT");
            resultMap.put("caseId", caseId);*/
        }
        resultMap.put("success", "true");
        resultMap.put("msg", "成功！");
        return resultMap;
    }

    /**
     * 【V1.1.0】描述：送达流程滚动
     *
     * @param saveDto {@link SentFlowRollInfoSaveDto}
     * @return Map<String, Object> 滚动标记信息
     * @author xiangyuyu
     * @date 2022-05-06 17:21
     */
    @Override
    @WorkFlowRollAnnotation
    @CaseChangeReportData
    public Map<String, Object> sentFlowRoll(SentFlowRollInfoSaveDto saveDto) {
        log.info("sentFlowRoll start...saveDto:{}" + saveDto);
        Map<String, Object> map = new HashMap<>(8);
        String caseId = saveDto.getCaseId();
        if (ObjectUtils.isEmpty(caseId)) {
            throw new BusinessException("请指定案件id");
        }
        map.put("closeSignal", "CLOSE-TRIGGER-SENT");
        String partyId = saveDto.getPartyId();
        if(!ObjectUtils.isEmpty(partyId)){
            map.put("workSubId", saveDto.getPartyId());
        }

        map.put("workId", caseId);
        String documentCataLogCode = saveDto.getDocumentCatalogCode();
        if (!ObjectUtils.isEmpty(documentCataLogCode)) {
            map.put("documentCatalogCode", documentCataLogCode);
        }
        log.info("sentFlowRoll end...map:{}" + map);
        return map;
    }



    /**
     * 【V2.0.0】描述：查询文书送达登记信息
     *
     * @param request {@link DocumentSentRegisterInfoRequest}
     * @return {@link Result<DocumentSentRegisterVo>} 文书送达登记信息
     * @author xiangyuyu
     * @date 2022-02-16 16:02
     */
    @Override
    public DocumentSentRegisterVo getDocumentSentRegisterInfo(DocumentSentRegisterInfoRequest request) {
        String dataSource = request.getDataSource();
        if(ApiVisitDataSourceEnum.PUNISH_MOBILE.getId().equals(dataSource)){
            return appDocumentSentFlowService.getDocumentSentRegisterInfo(request);
        }
        DocumentSendRecord documentSendRecord;
        String documentId = request.getDocumentId();
        String partyId = request.getPartyId();
        String caseId = request.getCaseId();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
        if (ObjectUtils.isEmpty(partyId)) {
            if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                throw new BusinessException("多当事人时送达流程指定当事人id");
            }
        }
        Example query = new Example(DocumentSendRecord.class);
        Example.Criteria criteria = query.createCriteria();
        criteria.andEqualTo("documentId",documentId)
                .andEqualTo("isSentRegister",YesOrNoEnum.YES.getCode())
                .andEqualTo("isDelete",YesOrNoEnum.NO.getCode());
        if(!ObjectUtils.isEmpty(partyId)){
            criteria.andEqualTo("partyId",partyId);
        }
        List<DocumentSendRecord> sentRegisterList = documentSendRecordMapper.selectByExample(query);
        if(!ObjectUtils.isEmpty(sentRegisterList) && sentRegisterList.size() > 0){
            documentSendRecord = sentRegisterList.get(Constant.INTEGER_0);
        } else {
            documentSendRecord = null;
        }
        DocumentSentRegisterVo vo = new DocumentSentRegisterVo();
        //获取文书目录编码
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        if (ObjectUtils.isEmpty(caseDocumentRecord)) {
            throw new BusinessException("未匹配到文书记录");
        }
        //设置审批通过时间
        vo.setDocumentApprovalTime(caseDocumentRecord.getDocumentApprovalTime());
        String documentCatalogCode = caseDocumentRecord.getDocumentCatalogCode();
        if (!ObjectUtils.isEmpty(documentSendRecord)) {
            BeanUtils.copyProperties(documentSendRecord, vo);
            vo.setSentAddress(documentSendRecord.getReceiverAccount());
            String receiver = documentSendRecord.getReceiverName();
            vo.setReceiver(receiver);
            vo.setReceiverName(SentRegisterReceiverTypeEnum.getValueByCode(receiver));
            vo.setSentWayName(SendWayEnum.getValueByCode(vo.getSentWay()));
            vo.setOperateUserId(documentSendRecord.getSenderId());
            vo.setOperateUserRealName(documentSendRecord.getSenderRealName());

        } else {
            /*
            取有效的送达地址确认书中的地址；
            若没有有效的送达地址确认书的，单位默认取注册地址
            自然人默认取个人联系地址
             */
            CaseDocumentSendinfoConfirm caseDocumentSendinfoConfirm = new CaseDocumentSendinfoConfirm();
            caseDocumentSendinfoConfirm.setCaseId(caseId);
            caseDocumentSendinfoConfirm.setDocumentCatalogCode(documentCatalogCode);
            caseDocumentSendinfoConfirm = caseDocumentSendinfoConfirmMapper.selectOne(caseDocumentSendinfoConfirm);
            String address = "";
            if (!ObjectUtils.isEmpty(caseDocumentSendinfoConfirm)) {
                //本人送达地址
                if (!ObjectUtils.isEmpty(caseDocumentSendinfoConfirm.getSendAddress())) {
                    address = caseDocumentSendinfoConfirm.getSendAddress();
                } else {
                    address = caseDocumentSendinfoConfirm.getReceiverAddress();
                }
                vo.setSentAddress(address);
            } else {
                //获取当事人信息
                CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto();
                queryDto.setPartyId(partyId);
                queryDto.setCaseId(caseId);
                List<CasePartiesInfoVo> casePartiesInfoList = casePartiesRecordService.getCasePartiesInfoList(queryDto);
                //getCasePartiesInfoList 已经排除了为空的情况，同时同一个案件一个partyId只存在1条记录
                CasePartiesInfoVo partyInfo = casePartiesInfoList.get(Constant.INTEGER_0);
                address = partyInfo.getAddress();
                vo.setSentAddress(address);
            }
        }
        //获取附件信息
        vo.setSentReceiptList(getSentRegisterAttachmentInfo(caseId, AttachmentTypeEnum.SENT_RECEIPT.getCode(), documentCatalogCode, partyId));
        vo.setSentEvidenceList(getSentRegisterAttachmentInfo(caseId, AttachmentTypeEnum.SENT_EVIDENCE.getCode(), documentCatalogCode, partyId));

        //案件环节、阶段信息赋值
        vo.setCaseId(caseId);
        vo.setDocumentId(documentId);
        vo.setCaseStageCode(caseMainInfo.getCaseCurrentStageCode());
        vo.setCaseStageName(caseMainInfo.getCaseCurrentStageName());
        vo.setCaseLinkCode(caseMainInfo.getCaseCurrentLinkCode());
        vo.setCaseLinkName(caseMainInfo.getCaseCurrentLinkName());
        return vo;
    }

    /**
     * 【V1.0.0】描述：保存文书送达登记
     *
     * @param saveDto {@link DocumentSentRegisterSaveDto}
     * @return {@link Result <String>} 保存结果
     * @author xiangyuyu
     * @date 2022-02-16 16:02
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> saveDocumentSentRegister(DocumentSentRegisterSaveDto saveDto) {
        String dataSource = saveDto.getDataSource();
        if(ApiVisitDataSourceEnum.PUNISH_MOBILE.getId().equals(dataSource)){
            return appDocumentSentFlowService.saveDocumentSentRegister(saveDto);
        }
        String caseId = saveDto.getCaseId();
        String documentCatalogCode = saveDto.getDocumentCatalogCode();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String partyId = saveDto.getPartyId();
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
            if (ObjectUtils.isEmpty(partyId)) {
                if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                    throw new BusinessException("多当事人时送达流程指定当事人id");
                }
            }
            Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
            partyId = map.get("partyId");
        }

        if(ObjectUtils.isEmpty(caseMainInfo)){
            throw new BusinessException("未匹配到案件信息");
        }
        String documentId = saveDto.getDocumentId();
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        if(ObjectUtils.isEmpty(caseDocumentRecord)){
            throw new BusinessException("未匹配文书记录");
        }
        //送达时间校验
        //送达时间限制在需要审批的文书取审批通过时间和当前时间之间的时间
        LocalDateTime documentApprovalTime = caseDocumentRecord.getDocumentApprovalTime();
        if (ObjectUtils.isEmpty(documentApprovalTime)) {
            documentApprovalTime = caseDocumentRecord.getDocumentCreateTime();
        }
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime sentTimeCheck = BaseUtil.stringToLocalDateTime(saveDto.getSentTime());
        if (sentTimeCheck.isBefore(documentApprovalTime) || sentTimeCheck.isAfter(now)) {
            throw new BusinessException("送达时间必须在审批通过时间和当前时间之间");
        }

        //非办案人员不允许操作
        List<String> handlerUserIdList = new ArrayList<>();
        List<CaseHandlePersonRecordVo> caseHandlePersonRecordList
                = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
        if(!ObjectUtils.isEmpty(caseHandlePersonRecordList) && caseHandlePersonRecordList.size() > 0){
            caseHandlePersonRecordList.forEach(e->{
                handlerUserIdList.add(e.getHandlePersonId());
            });
        }
        UserDTO userInfo = UserUtil.getUserInfo();
        if (!ObjectUtils.isEmpty(userInfo)) {
            String userId = userInfo.getUserId() + "";
            if (!handlerUserIdList.contains(userId)) {
                throw new BusinessException("非该案件办案人员无法进行此操作");
            }
        } else {
            throw new BusinessException("登录失效-saveDocumentSentRegister");
        }

        String caseStatus = caseMainInfo.getCaseStatus();
        String caseType = caseMainInfo.getCaseType();
        if (!CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
            if(CaseStatusEnum.END_CASE.getCode().equals(caseStatus)) {
                //结案
                //如果存在行政处罚撤销决定书，可以送达
                //V1.1.3结案时可以操作
//                CaseDocumentRecordDto documentInfo = caseDocumentRecordService.getCaseDocumentRecordByKindCode(caseId,Constant.STRING_KIND_CODE_XZCFCXJDS);
//                if(ObjectUtils.isEmpty(documentInfo)){
//                    throw new BusinessException("案件结案状态时无法进行此操作");
//                }
            } else if(CaseStatusEnum.TERMINATE.getCode().equals(caseStatus)) {
                //终止
                throw new BusinessException("案件终止状态时无法进行此操作");
            }
        }

        DocumentSendRecord documentSendRecord = new DocumentSendRecord();
        documentSendRecord.setPartyId(partyId);
        documentSendRecord.setIsSentRegister(YesOrNoEnum.YES.getCode());
        String recordSaveType = saveDto.getOperateType();
        String id;
        try {
            LocalDateTime sentTime = LocalDateTime.parse(saveDto.getSentTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            documentSendRecord.setSentTime(sentTime);
            if (!ObjectUtils.isEmpty(userInfo)) {
                saveDto.setOperateUserId(userInfo.getUserId() + "");
                saveDto.setOperateUserRealName(userInfo.getRealName());
            }
            documentSendRecord.setDocumentId(documentId);
            documentSendRecord.setReceiverAccount(saveDto.getSentAddress());
            documentSendRecord.setSentWay(saveDto.getSentWay());
            String receiver = saveDto.getReceiver();
            documentSendRecord.setReceiverName(receiver);
            String receiverType = SentRegisterReceiverTypeEnum.getValueByCode(receiver);
            /*
                按照要求(receiver、receiverType)应该存中文name，
                receiverType 代表1-受送达人/2-委托代理人/3-代收人（中文），
                receiver 存的是具体收件人的名字，
                但是pc端送达登记没有具体签收人姓名，
                那么，就默认存储签收人的类型（本来应该是要中文，但是为了与旧数据保持一致，后续处理旧数据方便，就用receiver编码字段
                【20220808】
             */
            receiverType = SentRegisterReceiverTypeEnum.SSDR.getCode().equals(receiver)?"当事人":receiverType;
            if (ObjectUtils.isEmpty(receiverType)) {
                receiverType = "当事人";
            }
            documentSendRecord.setReceiverType(receiverType);
            documentSendRecord.setReceiverRelation(saveDto.getReceiverRelation());
            documentSendRecord.setWitnessAddress(saveDto.getWitnessAddress());
            documentSendRecord.setRemark(saveDto.getRemark());
            documentSendRecord.setSenderId(saveDto.getOperateUserId());
            documentSendRecord.setSenderRealName(saveDto.getOperateUserRealName());
            documentSendRecord.setSendStatus(DocumentSendStatusEnum.SEND_SUCCESS.getCode());
            if (RecordSaveTypeEnum.MOD.getCode().equals(recordSaveType)) {
                id = saveDto.getId();
                if (ObjectUtils.isEmpty(id)) {
                    return Result.error(Constant.STRING_NO_PRIMARY_KEY);
                } else {
                    DocumentSentRegisterVo vo = getDocumentSentRegister(id);
                    if (ObjectUtils.isEmpty(vo)) {
                        return Result.error("未匹配到文书送达登记的记录");
                    }
                    //将送达登记信息更新至文书发送记录表
                    Example updateE = new Example(DocumentSendRecord.class);
                    updateE.createCriteria().andEqualTo("id", id);
                    documentSendRecord.setId(id);

                    documentSendRecordMapper.updateByExampleSelective(documentSendRecord, updateE);
                }
            } else {
                id = BaseUtil.createUid();
                BeanUtils.copyProperties(saveDto, documentSendRecord);
                documentSendRecord.setId(id);
                documentSendRecordMapper.insertSelective(documentSendRecord);
            }
            List<CaseAttachmentInfoSaveDto> caseAttachmentInfoList = new ArrayList<>();
            if (!ObjectUtils.isEmpty(saveDto.getSentReceiptList())) {
                caseAttachmentInfoList.addAll(saveDto.getSentReceiptList());
            }
            if (!ObjectUtils.isEmpty(saveDto.getSentEvidenceList())) {
                caseAttachmentInfoList.addAll(saveDto.getSentEvidenceList());
            }
            String finalPartyId = partyId;
            caseAttachmentInfoList.forEach(e -> {
                CaseAppendixRecord caseAppendixRecord = new CaseAppendixRecord();
                String attachmentId = e.getId();
                if (ObjectUtils.isEmpty(attachmentId)) {
                    BeanUtils.copyProperties(e, caseAppendixRecord);
                    caseAppendixRecord.setId(BaseUtil.createUid());
                    caseAppendixRecord.setCaseId(saveDto.getCaseId());
                    caseAppendixRecord.setCaseStageName(saveDto.getCaseStageName());
                    caseAppendixRecord.setCaseStageCode(saveDto.getCaseStageCode());
                    caseAppendixRecord.setCaseLinkCode(saveDto.getCaseLinkCode());
                    caseAppendixRecord.setCaseLinkName(saveDto.getCaseLinkName());
                    caseAppendixRecord.setDocumentCatalogCode(saveDto.getDocumentCatalogCode());
                    if(!ObjectUtils.isEmpty(userInfo)){
                        caseAppendixRecord.setUploadUserId(userInfo.getUserId() + "");
                        caseAppendixRecord.setUploadUserName(userInfo.getRealName());
                    }
                    caseAppendixRecord.setUploadTime(LocalDateTime.now());
                    String appendixTypeId = caseAppendixRecord.getAppendixTypeId();
                    if(ObjectUtils.isEmpty(appendixTypeId)){
                        throw new BusinessException("未指定附件类型id【"+caseAppendixRecord.getAppendixName()+"】");
                    }
                    String appendixUrl = caseAppendixRecord.getAppendixUrl();
                    if(ObjectUtils.isEmpty(appendixUrl)){
                        throw new BusinessException("未指定附件地址【"+caseAppendixRecord.getAppendixName()+"】");
                    }
                    caseAppendixRecord.setPartyId(finalPartyId);
                    caseAppendixRecordMapper.insertSelective(caseAppendixRecord);
                }
            });
            Map<String,Object> map = new HashMap<>(4);

            SentFlowRollInfoSaveDto sendFlowRollInfo = new SentFlowRollInfoSaveDto();
            sendFlowRollInfo.setCaseId(saveDto.getCaseId());
            sendFlowRollInfo.setPartyId(partyId);
            sendFlowRollInfo.setDocumentCatalogCode(documentCatalogCode);
            map = documentSentFlowService.sentFlowRoll(sendFlowRollInfo);
            map.put("success","true");
            map.put("msg","成功！");
            //更新文书记录
            if (checkDocumentIsAllSend(caseId, documentId)) {
                String sendStatus = DocumentSendStatusEnum.SEND_SUCCESS.getCode();
                caseDocumentRecordService.updateDocumentSentInfo(documentId, sentTime, sendStatus);
                triggerDecisionRevokeDealAfterSent(caseId,documentCatalogCode);
            }
        } catch (Exception e) {
            if (e.getMessage().contains(Constant.STRING_DUPLICATE_ENTRY) ||
                    e.getMessage().contains(Constant.STRING_DUPLICATE_ENTRY_LOWER)) {
                throw new BusinessException("请勿重复添加");
            } else {
                throw e;
            }
        }
        return Result.success(Constant.STRING_SAVE_SUCCESS, id);
    }

    /**
     * 描述：获取送达登记的附件信息
     *
     * @param caseId              案件id
     * @param attachmentTypeId    附件类型id
     * @param documentCatalogCode 文书目录编码
     * @param partyId             当事人id
     * @return {@link List<CaseAttachmentInfoVo>} 送达登记的附件信息
     * @author xiangyuyu
     * @date 2022-03-07 10:16
     */
    private List<CaseAttachmentInfoVo> getSentRegisterAttachmentInfo(String caseId, String attachmentTypeId, String documentCatalogCode, String partyId) {
        CaseAttachmentInfoQueryDto queryDto = new CaseAttachmentInfoQueryDto();
        queryDto.setCaseId(caseId);
        queryDto.setAttachmentTypeId(attachmentTypeId);
        queryDto.setDocumentCatalogCode(documentCatalogCode);
        if(!ObjectUtils.isEmpty(partyId)){
            queryDto.setPartyId(partyId);
        }

        List<CaseAttachmentInfoVo> caseAttachmentInfoList = caseAppendixRecordMapper.selectCaseAttachmentList(queryDto);
        return caseAttachmentInfoList;
    }

    /**
     * 【V1.0.0】描述：根据唯一标识查询文书送达登记
     *
     * @param id 唯一标识
     * @return {@link DocumentSentRegisterVo} 文书送达登记
     * @author xiangyuyu
     * @date 2022-02-16 16:02
     */
    @Override
    public DocumentSentRegisterVo getDocumentSentRegister(String id) {
        DocumentSendRecord documentSendRecord = documentSendRecordMapper.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(documentSendRecord)) {
            throw new BusinessException("未匹配到文书送达登记的记录");
        } else {
            if(!YesOrNoEnum.YES.getCode().equals(documentSendRecord.getIsSentRegister())){
                throw new BusinessException("无效的送达登记主键id");
            }
        }
        DocumentSentRegisterVo vo = new DocumentSentRegisterVo();
        BeanUtils.copyProperties(documentSendRecord, vo);
        vo.setSentAddress(documentSendRecord.getReceiverAccount());
        vo.setReceiver(documentSendRecord.getReceiverName());
        vo.setOperateUserId(documentSendRecord.getSenderId());
        vo.setOperateUserRealName(documentSendRecord.getSenderRealName());

        //获取附件信息
        CaseAttachmentInfoQueryDto queryDto = new CaseAttachmentInfoQueryDto();
        queryDto.setCaseId(documentSendRecord.getCaseId());
        //获取文书目录编码
        String documentId = documentSendRecord.getDocumentId();
        CaseDocumentRecordVo caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecordInfo(documentId);
        if (ObjectUtils.isEmpty(documentSendRecord)) {
            throw new BusinessException("未匹配到文书记录");
        }

        CaseAttachmentInfoQueryDto q = new CaseAttachmentInfoQueryDto();
        String caseId = caseDocumentRecord.getCaseId();
        String documentCatalogCode = caseDocumentRecord.getDocumentCatalogCode();
        q.setCaseId(caseId);
        q.setDocumentCatalogCode(documentCatalogCode);
        q.setAttachmentTypeId(AttachmentTypeEnum.SENT_RECEIPT.getCode());
        //获取附件信息
        vo.setSentReceiptList(caseAppendixRecordService.getCaseAttachmentInfoList(q));
        q.setAttachmentTypeId(AttachmentTypeEnum.SENT_EVIDENCE.getCode());
        vo.setSentEvidenceList(caseAppendixRecordService.getCaseAttachmentInfoList(q));
        return vo;
    }

    @Override
    public List<DocumentSendRecordByPartiesVo> getDocumentSendRecordByParties(DocumentSendRecordByPartiesQueryDto documentSendRecordByPartiesQueryDto) {
        List<DocumentSendRecordByPartiesVo> records = new ArrayList<>();
        //判断是否为多当事人分别处罚案件
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(documentSendRecordByPartiesQueryDto.getCaseId());
        if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(caseMainInfo.getCasePartiesReasonType())
                && HandleTypeEnum.PART_PUNISH.getCode().equals(caseMainInfo.getHandleType())) {
            //查询文书目录编码
            CaseDocumentRecord caseDocumentRecord = caseDocumentRecordMapper.selectByPrimaryKey(documentSendRecordByPartiesQueryDto.getDocumentId());
            records = documentSendRecordMapper.selectDocumentSendRecordListByPartiesOfPartPunish(caseMainInfo.getId(), caseDocumentRecord.getDocumentCatalogCode());
        } else {
            //单当事人或多当事人合并处罚
            records = documentSendRecordMapper.selectDocumentSendRecordListByPartiesOfMergePunish(documentSendRecordByPartiesQueryDto);
            //查询送达回证文书编码
            List<String> SDHZList = getSDHZList(documentSendRecordByPartiesQueryDto.getDocumentId());
            for (DocumentSendRecordByPartiesVo recordVo : records) {
                //1.判断是否有送达记录且送达成功
                if (!DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(recordVo.getSendStatusId())) {
                    //1.送达回证编码是否存在
                    if (SDHZList.isEmpty()) {
                        break;
                    }
                    //2.判断是否存在送达回证记录
                    List<DocumentSendRecordByPartiesVo> SDHZSendRecords = documentSendRecordMapper.selectDocumentSendRecordByCaseIdAndCatalogCodeAndPartyId(recordVo.getCaseId(), SDHZList, recordVo.getPartyId());
                    if (SDHZSendRecords.isEmpty()) {
                        continue;
                    }
                    //2.送达回证记录送达成功则设置成功状态
                    DocumentSendRecordByPartiesVo SDHZSendRecord = SDHZSendRecords.get(0);
                    if (DocumentSendStatusEnum.SEND_SUCCESS.getCode().equals(SDHZSendRecord.getSendStatusId())) {
                        recordVo.setSendStatusId(SDHZSendRecord.getSendStatusId());
                        recordVo.setSentTime(SDHZSendRecord.getSentTime());
                    }
                }

            }
        }

        records.forEach(vo -> {
            if (ObjectUtils.isEmpty(vo.getDocumentId())) {
                vo.setDocumentId(documentSendRecordByPartiesQueryDto.getDocumentId());
            }
            if (ObjectUtils.isEmpty(vo.getSendStatusId())) {
                vo.setSendStatusId(DocumentSendStatusEnum.WAIT_TO_SEND.getCode());
            }
            vo.setSendStatusName(DocumentSendStatusEnum.getValueByCode(vo.getSendStatusId()));
            vo.setPartyTypeName(PartyTypeEnum.getValueByCode(vo.getPartyTypeId()));
            if (ObjectUtils.isEmpty(vo.getSendDesc())) {
                vo.setSendDesc("未签署");
            }
            //当事人类型为公司法人时设置单位类型名称
            if (PartyTypeEnum.LEGAL.getCode().equals(vo.getPartyTypeId())) {
                vo.setEntTypeName(EnterTypeEnum.getValueByCode(vo.getEntTypeId()));
            }
        });

        return records;
    }

    /**
     * 描述：触发处罚决定撤销相关操作
     *
     * @param caseId          案件id
     * @param documentCatalog 文书目录编码
     * @author xiangyuyu
     * @date 2022/8/1
     * @since 1.3.2
     */
    public void triggerDecisionRevokeDealAfterSent(String caseId, String documentCatalog) {
        log.info("triggerDecisionRevokeDealAfterSent start...caseId:{},documentCatalog:{}", caseId, documentCatalog);
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo
                = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalog);
        if (ObjectUtils.isEmpty(configBusiParamDocumentInfo)) {
            throw new BusinessException("未匹配到文书配置信息-documentCatalogCode：" + documentCatalog);
        }
        String kindCode = configBusiParamDocumentInfo.getDocumentKindCode();
        //处罚撤销决定书送达后进行
        if (Constant.STRING_KIND_CODE_XZCFCXJDS.equals(kindCode)) {
            //获取后续操作类型信息
            CasePunishDecisionRevokeRecordVo vo = casePunishDecisionRevokeRecordService.getCasePunishDecisionRevokeRecordBasicInfo(caseId);
            if (!ObjectUtils.isEmpty(vo)) {
                casePunishDecisionRevokeRecordService.dealAfterPunishRevoke(caseId, vo.getDealAfterRevokeTypeCode());
            }
        }
        log.info("triggerDecisionRevokeDealAfterSent end");
    }

    /**
     * 描述： 发送文书短信
     *
     * @author: zhengqiang
     * @date: 2022/8/27
     * @param: smsDto
     * @return {@link Result< String>}
     **/
    @Override
    public Result<String> sendDocumentSms(SendDocumentSmsDto smsDto) {
        log.info("confirmSendMsg start... saveDto:{}:" + smsDto);
        String tel = smsDto.getReceiverAccount();
        String username = smsDto.getReceiverName();
        String documentId = smsDto.getDocumentId();
        String content = assembleSmsContentProvince(tel, username, documentId,null);
        String sendResult = sendSmsProvince(tel, content, "");
        if (!ObjectUtils.isEmpty(sendResult)) {
            return Result.error(Constant.STRING_FAIL_CH);
        } else {
            //短信发送成功更新送达记录
            LocalDateTime sentTime = LocalDateTime.now();
            String sendStatus = DocumentSendStatusEnum.SEND_SUCCESS.getCode();
            caseDocumentRecordService.updateDocumentSentInfo(documentId, sentTime, sendStatus);
            return Result.success(Constant.STRING_SUCCESS_CH);
        }
    }

    @Override
    public Result<String> sendDocumentSmsZlb(SendDocumentSmsZlbDto smsDto) {
        // 先给当事人发送短信
        // 文书id不能为空
        if (cfRedisRepository.exists(RedisUtil.REDIS_PREFIX_ZLB+"SD"+smsDto.getReceiverAccount())){
            throw new BusinessException("需间隔一分钟，请勿频繁操作");
        }
        String documentId = smsDto.getDocumentId();
        String caseId = smsDto.getCaseId();
        String documentCatalogCode = smsDto.getDocumentCatalogCode();
        //收件人名称不能为空
        String receiverName = smsDto.getReceiverName();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        // 当事人id
        String partyId = smsDto.getPartyId();
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
            if (ObjectUtils.isEmpty(partyId)) {
                if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)) {
                    throw new BusinessException("多当事人时送达流程指定当事人id");
                }
            }
            Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
            partyId = map.get("partyId");
        }
        boolean flag = false;
        Example example =  new Example(CaseDocumentRecord.class);
        example.createCriteria().andEqualTo("caseId",caseId).andEqualTo("partyId",partyId)
                .andEqualTo("documentCatalogCode",documentCatalogCode)
                .andEqualTo("documentRecordStatus",Constant.STRING_1);
        List<CaseDocumentRecord> caseDocumentRecords = caseDocumentRecordMapper.selectByExample(example);
        if (ObjectUtils.isEmpty(caseDocumentRecords) || caseDocumentRecords.size() == 0) {
            // 没有送达文书信息,生成送达文书
            StageDocCommonHtmlRequest request = new StageDocCommonHtmlRequest();
            request.setCaseId(caseId);
            request.setDocumentCatalogCode(documentCatalogCode);
            request.setDocumentId(documentId);
            request.setPartyId(partyId);
            DocumentCommonFormDataVo commonDocumentFormData = stageDocCommonOperateService.getCommonDocumentFormData(request);
            HashMap<String, Object> dataMap = (HashMap<String, Object>) commonDocumentFormData.getDataMap();
            dataMap.put("SDDZQRS_SJR", receiverName);
            StageDocCommonOperateSaveDto saveDto = new StageDocCommonOperateSaveDto();
            saveDto.setPartyId(partyId);
            saveDto.setDocumentCatalogCode(documentCatalogCode);
            saveDto.setBelongDocumentId(documentId);
            saveDto.setCaseId(caseId);
            saveDto.setDataMap(dataMap);
            //浙里办的送达去掉验证，也可表示为浙里办送达,也可表达为所有浙里办操作的文书
            zlbCaseDocumentRecordDto zlbCaseDocumentRecordDto = new zlbCaseDocumentRecordDto();
            zlbCaseDocumentRecordDto.setZlbType(Constant.STRING_1);
            saveDto.setZlbCaseDocumentRecordDto(zlbCaseDocumentRecordDto);
            stageDocCommonOperateService.saveDocInfo(saveDto);
            flag = true;
        }
        // 发送短信，修改成浙里办
        dataToZlbSms(smsDto,flag);
        return Result.success(Constant.STRING_SUCCESS_CH);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> delWithdrawZlb(WithdrawZlbDto withdrawZlbDto) {
        // 撤回逻辑
        CaseDocumentRecord caseDocumentRecord =  new CaseDocumentRecord();
        caseDocumentRecord.setId(withdrawZlbDto.getDocumentId());
        caseDocumentRecord.setZlbService(Constant.STRING_0);
        caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
        CaseDocumentRecordDelRequest caseDocumentRecordDelRequest = new CaseDocumentRecordDelRequest();
        caseDocumentRecordDelRequest.setCaseId(withdrawZlbDto.getCaseId());
        caseDocumentRecordDelRequest.setPartyId(withdrawZlbDto.getPartyId());
        caseDocumentRecordDelRequest.setDocumentId(withdrawZlbDto.getSendDocumentId());
        caseDocumentRecordDelRequest.setDocumentCatalogCode(withdrawZlbDto.getDocumentCatalogCode());
        int num = caseDocumentRecordService.delCaseDocumentRecordInfo(caseDocumentRecordDelRequest);
        return Result.success("撤回成功");
    }

    /**
     * 描述: 浙里办端发送消息，短信
     *
     * @param smsDto
     * @return void
     * @author zhanghongqiang
     * @Date 2022/12/7
     */
    private void dataToZlbSms(SendDocumentSmsZlbDto smsDto,boolean flag) {
        String receiverAccount = smsDto.getReceiverAccount();
        // 发送短信判断60秒
        if (cfRedisRepository.exists(RedisUtil.REDIS_PREFIX_ZLB+"SD"+receiverAccount)){
            throw new BusinessException("需间隔一分钟，请勿频繁操作");
        }
        String documentId = smsDto.getDocumentId();
        String receiverName = smsDto.getReceiverName();
        String content = assembleSmsContentProvince(receiverAccount, receiverName, documentId,Constant.STRING_1);
        String sendResult = sendSmsProvince(receiverAccount, content, "");
        if (!ObjectUtils.isEmpty(sendResult)) {
            throw  new BusinessException("短信发送失败");
        }
        cfRedisRepository.setExpire(RedisUtil.REDIS_PREFIX_ZLB+"SD"+receiverAccount,receiverAccount,60);
        // 更新文书的状态,清除掉送达地址确认书，送达地址确认书不在浙里办展示
        if (flag){
            CaseDocumentRecord caseDocumentRecord = new CaseDocumentRecord();
            caseDocumentRecord.setId(documentId);
            caseDocumentRecord.setZlbService(Constant.STRING_1);
            caseDocumentRecord.setZlbServicePhone(receiverAccount);
            caseDocumentRecord.setZlbServiceName(receiverName);
            caseDocumentRecord.setZlbServiceTime(DateUtil.dateToLocalDateTime(new Date()));
            caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
        }
    }

}
